Swift: CGRect, CGSize & CGPoint

du gör (förmodligen) fel

Andyy Hope
andyy hoppas

följ
feb 2, 2016 · 4 min läs

det har varit ungefär en solid åtta månader sedan jag först bestämde mig för att hoppa helt in i det snabba maskhålet. Under dessa månader har jag långsamt lärt mig att sluta skriva Objective-C – stilkodmönster med Swift-syntax och började faktiskt dra nytta av det nya språket.

men en sak som jag nyligen har tagit upp är att jag fortfarande använder ful icke-Swift-liknande syntax med alla mina CGGeometry strukturer.

CGRect, CGSize, CGPoint

C syntax. Ett får i vargkläder

Jag har en stor känsla av att många Swift-utvecklare kommer att vara skyldiga till detta. Räck upp handen om du har använt någon av dessa i din kod:

let rect = CGRectMake(0, 0, 100, 100)let point = CGPointMake(0, 0)let size = CGSizeMake(100, 100)

uppdatering: från och med Swift 3 har dessa funktioner tagits bort.

Ja, jag trodde det. Men oroa dig inte, det är inget att skämmas för … än.det som är fel med detta är att det bryter Swifts kodningskonvention, det kommer fortfarande att fungera, men det ser mycket mer ut som något som om det hör hemma i Objective-C eller ens, vågar jag säga Det, Java. * shudders *

till en erfaren iOS-eller OSX-utvecklare, med en kort blick kan de enkelt berätta vad den koden gör. De behöver inte argumentetiketter på CGGeometry strukturer eftersom alla känner till dessa argument och deras sekvens av hjärtat. Förutom att de inte gör det.

mycket av vad Swift handlar om är att vara vänlig mot språk nykomlingar samt kompletta programmerings nybörjare. Om de skulle titta på den koden skulle de inte ha någon aning om vad dessa siffror representerar. Så låt oss alla lova att vara bra Swift-medborgare och börja använda Swift-versionerna:

let rect = CGRect(x: 0, y: 0, width: 100, height: 100)let size = CGSize(width: 100, height: 100)let point = CGPoint(x: 0, y: 0)

För lite extra syntax är verbositeten i vår kod helt förståelig vid första anblicken. En extra bonus med att användaCGGeometry struct initializer är att vi nu inte bara är begränsade till att använda CGFloat som argument kan vi också skicka in Int och Double!

noll

let rect = CGRectZerolet size = CGSizeZerolet point = CGPointZero

uppdatering: från och med Swift 3 har dessa funktioner tagits bort.

medan vi är på det, använder du förmodligen fortfarande dessa, amirit? lel.

Vi bör också uppdatera dessa för att använda den nyare, snabbare syntaxen. Men oroa dig inte, syntaxen är bara en extra karaktär längre. Kan du gissa vad det är?

let rect = CGRect.zerolet size = CGSize.zerolet point = CGPoint.zero

en annan sak att få dig ombord med detta är att Xcodes syntax highlighter, beroende på ditt färgschema, markerar .zero, vilket gör det lite lättare på din kognitiva belastning.

Value retrieval

CGRect frame = CGRectMake(0, 0, 100, 100)CGFloat width = CGRectGetWidth(frame)CGFloat height = CGRectGetHeight(frame)CGFloat maxX = CGRectGetMaxX(frame)CGFloat maxY = CGRectGetMaxY(frame)

uppdatering: från och med Swift 3 har dessa funktioner tagits bort.

Om du var eller fortfarande är en bra Objective-C medborgare, skulle du ha använt dessa värde getters när du ville ha ett specifikt värde av rect. Men vänta en sekund, varför får vi inte bara tillgång till värdena direkt?

CGFloat width = frame.size.widthCGFloat height = frame.size.height

av denna anledning bör dina applikationer undvika att direkt läsa och skriva data lagrade i CGRect-datastrukturen. Använd istället funktionerna som beskrivs här för att manipulera rektanglar och hämta deras egenskaper.

— Apple, Cggeometry Reference Documentation

det finns förmodligen fortfarande många av er som inte störde med sådana formaliteter, men det är ok. Swift har lindrat oss av ett sådant opretentiöst API och gav istället enkla punktnotationsvariabler.

let frame = CGRect(x: 0, y: 0, width: 100, height: 100)let width = frame.widthlet height = frame.heightlet maxX = frame.maxXlet maxY = frame.maxY

det finns många fler exempel på dessa niceties tillgängliga i Swift playgrounds som jag har tillhandahållit för att komplettera det här inlägget. Länken kommer att vara längst ner på sidan.

Mutability

let frame = CGRect(x: 0, y: 0, width: 100, height: 100)let view = UIView(frame: frame)view.frame.origin.x += 10

Du kan inte bara ändra enskilda värden för en vys ram, men du kan också ersätta hela understrukturer helt. Se:

let view = UIView(frame: .zero)view.frame.size = CGSize(width: 10, height: 10)view.frame.origin = CGPoint(x: 10, y: 10)

den här lilla funktionen ensam är tillräckligt med en anledning att sluta använda Objective-C. Mutability på CGRects utan att behöva skapa en ny helt och återställa värdet. Det var bara mindre än två år sedan att vi som Objective – C-utvecklare tvingades skriva rammodifieringskod så här:

CGRect frame = CGRectMake(0, 0, 100, 100);UIView *view = initWithFrame: frame];CGRect newFrame = view.frame;newFrame.size.width = view.frame.origin.x + 10;view.frame = newFrame;

Jag vet inte om dig, men att skriva som verkligen stressade mig. Skapa ennewFrame struct frånviews ram, ändra den och sedan återställa egenskapenframeview igen. Nej tack, inte någonsin, någonsin igen tack.

glöm inte

det finns också ett par andra konstruktioner inom UIKit för vilka dessa ändringar är tillämpliga på:

UIEdgeInsets var edgeInsets = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
edgeInsets.top += 10UIOffsetvar offset = UIOffset(horizontal: 10, vertical: 10)
offset.vertical += 10

Lämna ett svar

Din e-postadress kommer inte publiceras.