Sök…
Introduktion
Auto Layout beräknar dynamiskt storleken och positionen för alla vyer i din visningshierarki, baserat på begränsningar som finns på dessa vyer. Källa
Syntax
- NSLayoutConstraint (artikel: Vilken som helst, attribut: NSLayoutAttribut, relateradBy: NSLayoutRelation, toItem: Any ?, attribut: NSLayoutAttribute, multiplikator: CGFloat, konstant: CGFloat) // Skapa en kontrast programmatiskt
Ställa in begränsningar programmatiskt
Exempel på pannplåtkod
override func viewDidLoad() {
super.viewDidLoad()
let myView = UIView()
myView.backgroundColor = UIColor.blueColor()
myView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(myView)
// Add constraints code here
// ...
}
I exemplen nedan är Anchor Style den föredragna metoden framför NSLayoutConstraint
Style, men den är bara tillgänglig från iOS 9, så om du stöder iOS 8 bör du fortfarande använda NSLayoutConstraint
Style.
fastlåsning
Ankerstil
let margins = view.layoutMarginsGuide
myView.leadingAnchor.constraintEqualToAnchor(margins.leadingAnchor, constant: 20).active = true
- Förutom
leadingAnchor
finns det ocksåtrailingAnchor
,topAnchor
ochbottomAnchor
.
NSLayoutConstraint Style
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1.0, constant: 20.0).active = true
- Förutom
.Leading
finns också.Trailing
,.Top
och.Bottom
. - Förutom.
.LeadingMargin
finns det också.TrailingMargin
,.TopMargin
och.BottomMargin
.
Visuellt format språkstil
NSLayoutConstraint.constraintsWithVisualFormat("H:|-20-[myViewKey]", options: [], metrics: nil, views: ["myViewKey": myView])
Bredd och höjd
Ankerstil
myView.widthAnchor.constraintEqualToAnchor(nil, constant: 200).active = true
myView.heightAnchor.constraintEqualToAnchor(nil, constant: 100).active = true
NSLayoutConstraint Style
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 200).active = true
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Height, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1, constant: 100).active = true
Visuellt format språkstil
NSLayoutConstraint.constraintsWithVisualFormat("H:[myViewKey(200)]", options: [], metrics: nil, views: ["myViewKey": myView])
NSLayoutConstraint.constraintsWithVisualFormat("V:[myViewKey(100)]", options: [], metrics: nil, views: ["myViewKey": myView])
Centrum i behållaren
Ankerstil
myView.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor).active = true
myView.centerYAnchor.constraintEqualToAnchor(view.centerYAnchor).active = true
NSLayoutConstraint Style
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.CenterX, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.CenterX, multiplier: 1, constant: 0).active = true
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.CenterY, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.CenterY, multiplier: 1, constant: 0).active = true
Visuellt format språkstil
NSLayoutConstraint.constraintsWithVisualFormat("V:[viewKey]-(<=0)-[myViewKey]", options: NSLayoutFormatOptions.AlignAllCenterX, metrics: nil, views: ["myViewKey": myView, "viewKey": view])
NSLayoutConstraint.constraintsWithVisualFormat("H:[viewKey]-(<=0)-[myViewKey]", options: NSLayoutFormatOptions.AlignAllCenterY, metrics: nil, views: ["myViewKey": myView, "viewKey": view])
Hur man använder Auto Layout
Auto-layout används för att ordna vyer så att de ser bra ut på alla enheter och riktningar. Begränsningar är reglerna som säger hur allt ska fastställas. De inkluderar fästkanter, centrering och inställningsstorlekar, bland annat.
Autolayout är aktiverat som standard, men du kan kontrollera det här. Om du klickar på Main.storyboard i Project Navigator och sedan visar File inspector. Se till att automatisk layout och storleksklasser är markerade:
Auto layout begränsningar kan ställas in i Interface Builder eller i kod. I Interface Builder hittar du Auto Layout-verktygen längst ner till höger. Om du klickar på dem visas olika alternativ för att ställa in begränsningarna i en vy.
Om du vill ha olika begränsningar för olika enhetsstorlekar eller riktningar, kan du ställa in dem i alla alternativ för hAny Size Class i den nedre mitten.
Center begränsningar
Välj din knapp (eller vilken vy du vill centrera) på storyboard . Klicka sedan på justeringsknappen längst ner till höger. Välj Horizontally in Container
och Vertically in Container
. Klicka på "Lägg till två begränsningar".
Om det inte redan var perfekt centrerat kan du behöva göra en sak till. Klicka på knappen "Uppdatera ramar" som är två till vänster om knappen "Bädda in bunt" i nedre fältet.
Du kan också "uppdatera ramar vid behov" genom att trycka ihop ⌘ + ⌥ + = (Kommando + Alternativ och lika) efter att du valt vyn, det kan spara lite tid.
När du kör din app ska den nu vara centrerad, oavsett vilken enhetsstorlek du använder.
Ett annat sätt att centrera vyer med hjälp av Interface Builder är genom att klicka-klicka-dra. Säg att du vill centrera en UILabel
i en vy. Öppna Document Outline
i ditt storyboard genom att klicka på sidofältets knapp längst ner till vänster. Klicka och dra från etiketten till vyn medan du håller ctrl (kontroll), och en blå rad ska visas:
Vid släpp kommer en meny med begränsningsalternativ att visas:
Välj "Centrera horisontellt i behållare" och "Centrera vertikalt i behållare". Uppdatera ramar vid behov och voila! En centrerad etikett.
Alternativt kan du lägga till begränsningarna programmatiskt. Skapa begränsningarna och lägg till dem i önskade UI-element och vyer som följande exempel beskriver, där vi skapar en knapp och justerar den i mitten, horisontellt och vertikalt till dess övervakning:
Objective-C
- (void)viewDidLoad
{
[super viewDidLoad];
UIButton *yourButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 18)];
[yourButton setTitle:@"Button" forState:UIControlStateNormal];
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:yourButton attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]]; //Align veritcally center to superView
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:yourButton attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1 constant:0]]; //Align horizontally center to superView
[self.view addSubview:yourButton]; //Add button to superView
}
Snabb
override func viewDidLoad()
{
super.viewDidLoad()
let yourButton: UIButton = UIButton(frame: CGRect(x: 0, y: 0, width: 100, height: 18))
yourButton.setTitle("Button", forState: .Normal)
let centerVertically = NSLayoutConstraint(item: yourButton,
attribute: .CenterX,
relatedBy: .Equal,
toItem: view,
attribute: .CenterX,
multiplier: 1.0,
constant: 0.0)
let centerHorizontally = NSLayoutConstraint(item: yourButton,
attribute: .CenterY,
relatedBy: .Equal,
toItem: view,
attribute: .CenterY,
multiplier: 1.0,
constant: 0.0)
NSLayoutConstraint.activateConstraints([centerVertically, centerHorizontally])
}
Rymdsikt jämnt
Det är vanligt att två vyer ska vara sida vid sida, centrerade i deras övervakning. Det vanliga svaret på Stack Overflow är att bädda in dessa två vyer i en UIView
och centrera UIView
. Detta är inte nödvändigt eller rekommenderat. Från UILayoutGuide- dokumenten:
Det finns ett antal kostnader förknippade med att lägga till dummy-vyer i din visningshierarki. Först är det kostnaden för att skapa och underhålla vyn i sig. För det andra är dummy-vyn en fullständig medlem av visningshierarkin, vilket innebär att den lägger omkostnader till varje uppgift som hierarkin utför. Värst av allt kan den osynliga dummyvyn fånga meddelanden som är avsedda för andra vyer, vilket kan orsaka problem som är mycket svåra att hitta.
Du kan använda UILayoutGuide
att göra detta istället för att lägga till knapparna i en onödig UIView
. En UILayoutGuide
är i huvudsak ett rektangulärt utrymme som kan interagera med Auto Layout. Du lägger en UILayoutGuide
på vänster och höger sida av knapparna och ställer in deras bredd på att vara lika. Detta kommer att centrera knapparna. Så här gör du i kod:
Visuellt format språkstil
view.addSubview(button1)
view.addSubview(button2)
let leftSpace = UILayoutGuide()
view.addLayoutGuide(leftSpace)
let rightSpace = UILayoutGuide()
view.addLayoutGuide(rightSpace)
let views = [
"leftSpace" : leftSpace,
"button1" : button1,
"button2" : button2,
"rightSpace" : rightSpace
]
// Lay the buttons and layout guides out horizontally in a line.
// Put the layout guides on each end.
NSLayoutConstraint.activateConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[leftSpace][button1]-[button2][rightSpace]|", options: [], metrics: nil, views: views))
// Now set the layout guides widths equal, so that the space on the
// left and the right of the buttons will be equal
leftSpace.widthAnchor.constraintEqualToAnchor(rightSpace.widthAnchor).active = true
Ankerstil
let leadingSpace = UILayoutGuide()
let trailingSpace = UILayoutGuide()
view.addLayoutGuide(leadingSpace)
view.addLayoutGuide(trailingSpace)
leadingSpace.widthAnchor.constraintEqualToAnchor(trailingSpace.widthAnchor).active = true
leadingSpace.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor).active = true
leadingSpace.trailingAnchor.constraintEqualToAnchor(button1.leadingAnchor).active = true
trailingSpace.leadingAnchor.constraintEqualToAnchor(button2.trailingAnchor).active = true
trailingSpace.trailingAnchor.constraintEqualToAnchor(view.trailingAnchor).active = true
Du måste också lägga till vertikala begränsningar till detta, men det kommer att centrera knapparna i vyn utan att lägga till några "dummy" vyer! Detta sparar systemet från att slösa bort CPU-tid på att visa dessa "dummy" -vyer. Det här exemplet använder knappar, men du kan byta ut knappar för valfri vy du vill sätta begränsningar på.
Om du stöder iOS 8 eller tidigare är det enklaste sättet att skapa den här layouten att lägga till dolda dummy-vyer. Med iOS 9 kan du ersätta dummy-vyer med layoutguider.
Obs: Interface Builder har inte stöd för layoutguider ännu (Xcode 7.2.1). Så om du vill använda dem måste du skapa dina begränsningar i kod. Källa .
UILabel Intrinsic Storlek
Vi måste skapa en vy som har ett bildprefix till en text. text kan ha varierbar längd. Vi måste uppnå ett resultat där i bild + text alltid är i mitten av en överordnad vy.
Steg 1: Skapa först ett enskilt vyprojekt och namnge det som du väljer och öppna berättelsebrädets nävevy. Dra en vy med någon rimlig storlek och ställ in dess bakgrundsfärg till gul. Jag har ändrat storlek på min viewcontroller till 3,5 ″. Resultatet vy bör se ut så här
Steg 2: Nu lägger vi till begränsningar i den gula vyn. Till att börja med lägger vi till bredd- och höjdbegränsningar (Vänta en minut sa vi inte att den vyn har dynamisk bredd? Ok, vi kommer tillbaka till det senare) Lägg till Följande begränsningar enligt bilden nedan bryr sig inte med breddvärde, något värde kommer att göra det bra för bredden, håll det bara tillräckligt stort så att vi kan lägga till autolayouts ordentligt.
Efter att du har lagt till dessa två begränsningar ser du att XCode ger dig fel, som i bilden nedan kan vi se dem och förstå dem.
Vi har två fel (rött betyder fel) Som diskuterats ovan kan vi återvända till tvetydighetsdelen
Saknade begränsningar: Behöver begränsningar för: X-position: - Som diskuterats ovan har vi gett vyn en bredd och en höjd så att dess "BOUNDS" är definierade men vi har inte angett sitt ursprung så dess "FRAME" är inte definierat. Autolayout kan inte bestämma vad som kommer att vara X-positionen för vår gula vy
Saknade begränsningar: Behöver begränsningar för: Y-position: - Som diskuterats ovan har vi gett vyn en bredd och en höjd så dess "BOUNDS" är definierad men vi har inte angett sitt ursprung så dess "FRAME" är inte definierat. Autolayout kan inte bestämma vad som kommer att vara Y-positionen för vår gula vy. För att lösa detta måste vi ge autolayout något för att resolera X och Y. Eftersom vi inte kan ställa in ramar kommer vi att göra det autolayout-sättet. Lägg till följande begränsningar enligt bilden nedan kommer jag att förklara det senare
Vad vi har gjort är att vi har lagt till ett "vertikalt centrum" och "horisontellt centrum". Dessa begränsningar säger autolayout att vår gula vy alltid kommer att vara i centrum horisontellt: så X i bestämd samma är med vertikal begränsning och Y bestäms. (Du kan behöva justera ramen).
Steg 3: Nu är vår gula basvy klar. Vi lägger till prefixbilden som undervy av vår gula vy med följande begränsningar. Du kan välja valfri bild.
Eftersom vi har en fast dimension för vår prefixbild kommer vi att ha en fast breddhöjd för den här bildvisningen. Lägg till begränsningarna och fortsätt till nästa steg.
Steg 4: Lägg till en UIL-etikett som undervyn i vår gula vy och lägg till följande begränsningar
Som ni ser har jag bara gett relativa begränsningar till vår UILabel. Den har 8 poäng från prefixbilden och 0,0,0 baksida och botten från gul vy. Eftersom vi vill att bredden ska vara dynamisk ger vi inte bredd- eller höjdbegränsningar .
F: Varför får vi inga fel nu, vi har inte angett någon bredd och höjd? Svar: - Vi får fel eller varning bara när autolayout inte kan lösa något som är måste för att göra en vy på skärmen. Det är höjdbredd eller ursprung. Eftersom vår etikett är relativt gulvy och prefixbild och deras ramar är väl definierad autolayout kan beräkna ramen för vår etikett.
Steg 5: Nu om vi kommer ihåg kommer vi att inse att vi har gett en fast vy till den gula vyn men vi vill att den ska vara dynamisk beroende på texten på vår etikett. Så vi kommer att ändra vår breddbegränsning av gul vy. Bredd på gul vy är nödvändigt för att lösa tvetydighet men vi vill att det ska åsidosättas vid körning baserat på innehållet i UILabel. Så vi kommer att välja vår gula vy och gå till Storleksinspektör och minska prioriteten för breddbegränsning till 1 så att den kommer att vara över styrd. Följ bilden nedan.
Steg 6: Vi vill att UILabel ska utvidgas enligt text och trycka på vår gula vy. Så vi har minskat prioriteten för gul visningsbredd. Nu kommer vi att öka prioriteringen för textkomprimeringsmotstånd för vår UILabel. Vi vill att vår vy ska minska som ja, så vi kommer att öka prioriteringen av innehållskramning av UILabel. Följ bilden nedan
Som ni kan se har vi ökat prioritering av innehåll som kramar till 500 och prioritering av kompressionsmotstånd till 751 som framgångsrikt kommer att styra breddbegränsningens 1 prioritet.
Bygg nu och kör så kommer du att se något som följer.
Hur man animerar med Auto Layout
Utan automatisk layout utförs animationen genom att ändra bildens ram över tid. Med Auto Layout dikterar begränsningarna visningsramen, så du måste animera begränsningarna istället. Denna indirekt gör animering svårare att visualisera.
Så här animerar du med Auto Layout:
- Ändra konstanten för begränsningen efter skapandet med hjälp av periodiska samtal (
CADisplayLink
,dispatch_source_t
,dispatch_after
,NSTimer
). Ring sedanlayoutIfNeeded
att uppdatera begränsningen. Exempel:
Objective-C:
self.someConstraint.constant = 10.0;
[UIView animateWithDuration:0.25 animations:^{
[self.view layoutIfNeeded];
}];
Snabb:
self.someConstraint.constant = 10.0
UIView.animate(withDuration: 0.25, animations: self.view.layoutIfNeeded)
- Ändra begränsningarna och ring
[view layoutIfNeeded]
i ett animationsblock. Detta interpolerar mellan de två positionerna och ignorerar begränsningar under animeringen.
[UIView animateWithDuration:0.5 animations:^{
[view layoutIfNeeded];
}]
Ändra prioriteringarna för begränsningarna . Detta är mindre CPU-intensivt än att lägga till och ta bort begränsningar.
Ta bort alla begränsningar och använd autosizingmasker . För det senare måste du ställa in
view.translatesAutoresizingMaskIntoConstraints = YES
.Använd begränsningar som inte stör den avsedda animationen .
Använd en containervy . Placera övervakningen med begränsningar. Lägg sedan till en undervy med begränsningar som inte kämpar mot animeringen, t.ex.: ett centrum relativt till övervakningen. Detta tar bort en del av begränsningarna till övervakningen, så att de inte kämpar mot animeringen i undervyn.
Animera lager istället för vyer . Lageromvandlingar utlöser inte Auto Layout.
CABasicAnimation* ba = [CABasicAnimation animationWithKeyPath:@"transform"];
ba.autoreverses = YES;
ba.duration = 0.3;
ba.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(1.1, 1.1, 1)];
[v.layer addAnimation:ba forKey:nil];
Åtgärda layoutSubviews . Ring
[super layoutSubviews]
och finjustera begränsningarna.Ändra ramen i viewDidLayoutSubviews . Auto Layout tillämpas i
layoutSubviews
, så när du gjort det, ändra det iviewDidLayoutSubviews
.Välj bort Auto Layout och ställ in vyer manuellt. Du kan göra detta
layoutSubviews
/layout
utan att kalla superklassens implementering.
Snabbtips: om föräldrarna till den animerade vyn inte interpoleras (det vill säga, animationen hoppar från början till layoutIfNeeded()
), ring layoutIfNeeded()
i den djupaste vyn som är överordnade till vyn som är animerad (med andra ord , det påverkas inte av animationen). Jag vet inte exakt varför det här fungerar.
Lös UILabel Prioritetskonflikt
Problem : När du använder många etiketter i en vy får du kanske en varning :
Hur kan vi fixa denna varning ?
Lösning : Vi beräknar och ställer in prioriteringarna i ordning. Prioriteringarna måste skilja sig från etiketter. Det betyder att det som är viktigt kommer att få högre prioritet. I mitt fall till exempel ställer jag in de vertikala prioriteringarna för mina etiketter så här:
Jag satte högsta prioritet för första etiketten och den lägsta för fjärde etiketten.
I en ViewController tror jag att du är svår att se effekten av dessa prioriteringar. Det är dock mycket tydligt med UITableViewCell + uppskattning av cellhöjd.
Hoppas det här hjälper.
UIL-etikett & Parentview-storlek enligt text i UILabel
Steg för steg-guide: -
Steg 1: - Ställ in begränsning till UIView
- Ledande. 2) Topp. 3) Släp. (Från mainview)
Steg 2: - Ställ begränsningen till etikett 1
- Ledande 2) Topp 3) Släpvagn (från dess övervakning)
Steg 3: - Ställ in begränsningen till etikett 2
- Ledande 2) Topp 3) Släpvagn (från dess övervakning)
Steg 4: - Det mest knepiga ger UILabel från UIView.
Steg 5: - (Valfritt) Ställ in begränsningen till UIButton
- Ledande 2) Nedre 3) Släpvagn 4) Fast höjd (från huvudvy)
Utgång: -
Obs: - Se till att du har angett antal rader = 0 i egenskapen Label.
Jag hoppas att den här informationen är tillräckligt för att förstå Autoresize UIView enligt UILabels höjd och Autoresize UILabel enligt text.
Grundläggande språk för visuellt format: Begränsningar i kod!
HVFL är ett språk som är utformat för att begränsa UI-element på ett enkelt och snabbt sätt. Generellt sett har VFL en fördel jämfört med traditionell anpassning av användargränssnittet i Interface Builder eftersom det är mycket mer läsbart, tillgängligt och kompakt.
Här är ett exempel på VFL, där tre UIViews begränsas från vänster till höger, fyller superView.width
, med aGradeView
"H:|[bgView][aGradeView(40)][bGradeView(40)]|"
Det finns två axlar där vi kan begränsa UI-objekt, horisontellt och vertikalt.
Varje rad i VFL börjar alltid med H:
eller V:
. Om ingen av dessa finns, är standardalternativet H:
När vi går vidare har vi en pipeline. |
Denna symbol, eller röret, hänvisar till övervakningen. Om du tittar närmare på utdraget av VFL-koden ovan, märker du två av dessa pipelines.
Detta betecknar de två horisontella ändarna av övervakningen, yttre vänster och yttersta gränserna.
Nästa upp ser du några fyrkantiga parenteser, inom den första uppsättningen fyrkantiga parenteser har vi bgView
. När vi har fyrkantiga parenteser hänvisar det till ett UI-element, nu kanske du undrar hur vi upprättar en länk mellan namnet och det faktiska UI-elementet, kanske ett utlopp?
Jag täcker det i slutet av inlägget.
Om du tittar på det andra paret med fyrkantiga parenteser [aGradeView(50)]
, har vi några parenteser som är inkapslade inom också, när det är närvarande definierar det bredden / höjden beroende på axlarna, som i detta fall är 50 pixlar i bredd.
De första fyrkantiga parenteserna [bgView]
hade inte en uttrycklig bredd, vilket innebär att de kommer att sträcka sig ut så långt som möjligt.
Okej, det är det för grunderna, mer om avancerade saker i ett annat exempel.
// 1. create views UIView *blueView = [[UIView alloc] init]; blueView.backgroundColor = [UIColor blueColor]; [self.view addSubview:blueView]; UIView *redView = [[UIView alloc] init]; redView.backgroundColor = [UIColor redColor]; [self.view addSubview:redView]; // 2. forbid Autoresizing blueView.translatesAutoresizingMaskIntoConstraints = NO; redView.translatesAutoresizingMaskIntoConstraints = NO; // 3. make contraints // horizontal NSArray *blueH = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-20-[blueView]-20-|" options:NSLayoutFormatAlignAllLeft metrics:nil views:@{@"blueView" : blueView}]; [self.view addConstraints:blueH]; // vertical NSArray *blueVandRedV = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[blueView(50)]-20-[redView(==blueView)]" options:NSLayoutFormatAlignAllTrailing metrics:nil views:@{@"blueView" : blueView, @"redView" : redView}]; [self.view addConstraints:blueVandRedV]; NSLayoutConstraint *redW = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0]; [self.view addConstraint:redW];
Blandad användning av Auto Layout med icke-Auto Layout
Ibland kanske du vill utföra några ytterligare åtgärder för Auto Layout- beräkningar som gjorts av UIKit
själv.
Exempel: när du har en UIView
som har en maskLayer
, kan du behöva uppdatera maskLayer
så snart Auto Layout ändrar UIView
frame
// CustomView.m
- (void)layoutSubviews {
[super layoutSubviews];
// now you can assume Auto Layout did its job
// you can use view's frame in your calculations
CALayer maskLayer = self.maskLayer;
maskLayer.bounds = self.bounds;
...
}
eller om du vill vidta några ytterligare åtgärder till Auto Layout i ViewController
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
// now you can assume all your subviews are positioned/resized correctly
self.customView.frame = self.containerView.frame;
}
Proportionell layout
Begränsning skapad som
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1.0, constant: 20.0)
eller, ur matematisk synvinkel:
view.attribute * multiplier + constant (1)
Du kan använda multiplikator för att skapa proportionell layout för olika storleksfaktorer.
Exempel:
Turkosvy (V1) är en fyrkant med bredd proportionell övervakningsbredd med förhållandet 1: 1.1
Gary square (V2) är en undervy av V1. Bottenutrymme inställt med konstant = 60, Släpavstånd inställt med multiplikator = 1.125 och konstant = 0
Längsutrymme ställs in proportionellt, bottenutrymme ställs in som en konstant.
Obs: om view.attribute är lika med 0 (till exempel ledande utrymme), kommer begränsningsformeln (1) att vara lika 0. Du måste ändra andra begränsningsobjekt eller ställa in begränsning i förhållande till marginal för att view.attribute! = 0.
NSLayoutConstraint: Kontrakter i kod!
När vi arbetar med ett ramverk, om begränsningarna inte är för komplicerade, skulle vi bättre använda Interface Builder eller NSLayoutConstraint i kod för att göra det mindre nog, istället för att importera Masonry eller SnapKit.
- Objective-C
// 1. create views UIView *blueView = [[UIView alloc] init]; blueView.backgroundColor = [UIColor blueColor]; [self.view addSubview:blueView]; UIView *redView = [[UIView alloc] init]; redView.backgroundColor = [UIColor redColor]; [self.view addSubview:redView]; // 2. forbid Autoresizing blueView.translatesAutoresizingMaskIntoConstraints = NO; redView.translatesAutoresizingMaskIntoConstraints = NO; // 3. make contraints // 3.1 blueView NSLayoutConstraint *blueLeft = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1 constant:20]; [self.view addConstraint:blueLeft]; NSLayoutConstraint *blueTop = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1 constant:20]; [self.view addConstraint:blueTop]; NSLayoutConstraint *blueRight = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1 constant:-20]; [self.view addConstraint:blueRight]; NSLayoutConstraint *blueHeight = [NSLayoutConstraint constraintWithItem:blueView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1 constant:50]; [self.view addConstraint:blueHeight]; // 3.2 redView NSLayoutConstraint *redTop = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeBottom multiplier:1 constant:20]; [self.view addConstraint:redTop]; NSLayoutConstraint *redRight = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1 constant:-20]; [self.view addConstraint:redRight]; NSLayoutConstraint *redHeight = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeHeight multiplier:1 constant:0]; [self.view addConstraint:redHeight]; NSLayoutConstraint *redWidth = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:blueView attribute:NSLayoutAttributeWidth multiplier:0.5 constant:0]; [self.view addConstraint:redWidth];