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 och bottomAnchor .

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:

ange bildbeskrivning här

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.

ange bildbeskrivning här

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.

ange bildbeskrivning här

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".

Justering - Metod 1

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. Uppdatera ramar

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:

blå linje

Vid släpp kommer en meny med begränsningsalternativ att visas:

meny med begränsningsalternativ

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

ange bildbeskrivning här

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.

ange bildbeskrivning här

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

ange bildbeskrivning 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.

ange bildbeskrivning här

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. ange bildbeskrivning här

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

ange bildbeskrivning här

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.

ange bildbeskrivning här

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

ange bildbeskrivning här

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.

ange bildbeskrivning här

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

ange bildbeskrivning här

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.

ange bildbeskrivning här

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:

  1. Ändra konstanten för begränsningen efter skapandet med hjälp av periodiska samtal ( CADisplayLink , dispatch_source_t , dispatch_after , NSTimer ). Ring sedan layoutIfNeeded 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)
  1. Ä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];
}]
  1. Ändra prioriteringarna för begränsningarna . Detta är mindre CPU-intensivt än att lägga till och ta bort begränsningar.

  2. Ta bort alla begränsningar och använd autosizingmasker . För det senare måste du ställa in view.translatesAutoresizingMaskIntoConstraints = YES .

  3. Använd begränsningar som inte stör den avsedda animationen .

  4. 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.

  5. 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];
  1. Åtgärda layoutSubviews . Ring [super layoutSubviews] och finjustera begränsningarna.

  2. Ändra ramen i viewDidLayoutSubviews . Auto Layout tillämpas i layoutSubviews , så när du gjort det, ändra det i viewDidLayoutSubviews .

  3. 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 :

ange bildbeskrivning här

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.

ange bildbeskrivning här

ange bildbeskrivning här

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

  1. Ledande. 2) Topp. 3) Släp. (Från mainview)

ange bildbeskrivning här

Steg 2: - Ställ begränsningen till etikett 1

  1. Ledande 2) Topp 3) Släpvagn (från dess övervakning)

ange bildbeskrivning här

Steg 3: - Ställ in begränsningen till etikett 2

  1. Ledande 2) Topp 3) Släpvagn (från dess övervakning)

ange bildbeskrivning här

Steg 4: - Det mest knepiga ger UILabel från UIView.

ange bildbeskrivning här

Steg 5: - (Valfritt) Ställ in begränsningen till UIButton

  1. Ledande 2) Nedre 3) Släpvagn 4) Fast höjd (från huvudvy)

ange bildbeskrivning här

Utgång: -

ange bildbeskrivning här

Obs: - Se till att du har angett antal rader = 0 i egenskapen Label.

ange bildbeskrivning här

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.


till exempel:
VFL_demo

    // 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.

ange bildbeskrivning här

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.

till exempel:
ange bildbeskrivning här

  • 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];


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow