iOS
Automatische lay-out
Zoeken…
Invoering
Auto Layout berekent dynamisch de grootte en positie van alle weergaven in uw weergavehiërarchie, op basis van beperkingen die in die weergaven worden geplaatst. Bron
Syntaxis
- NSLayoutConstraint (item: Any, kenmerk: NSLayoutAttribute, gerelateerdBy: NSLayoutRelation, toItem: Any ?, kenmerk: NSLayoutAttribute, vermenigvuldiger: CGFloat, constant: CGFloat) // Programmeer een contraint
Beperkingen programmatisch instellen
Voorbeeld van ketelplaatcode
override func viewDidLoad() {
super.viewDidLoad()
let myView = UIView()
myView.backgroundColor = UIColor.blueColor()
myView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(myView)
// Add constraints code here
// ...
}
In de onderstaande voorbeelden heeft de NSLayoutConstraint
de voorkeur boven NSLayoutConstraint
stijl, maar deze is alleen beschikbaar vanaf iOS 9, dus als u iOS 8 ondersteunt, moet u nog steeds NSLayoutConstraint
stijl gebruiken.
pinning
Ankerstijl
let margins = view.layoutMarginsGuide
myView.leadingAnchor.constraintEqualToAnchor(margins.leadingAnchor, constant: 20).active = true
- Naast
leadingAnchor
is er ooktrailingAnchor
,topAnchor
enbottomAnchor
.
NSLayoutConstraint Style
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1.0, constant: 20.0).active = true
- Naast
.Leading
er ook.Trailing
,.Top
en.Bottom
. - Naast
.LeadingMargin
er ook.TrailingMargin
,.TopMargin
en.BottomMargin
.
Visueel formaat Taalstijl
NSLayoutConstraint.constraintsWithVisualFormat("H:|-20-[myViewKey]", options: [], metrics: nil, views: ["myViewKey": myView])
Breedte en hoogte
Ankerstijl
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
Visueel formaat Taalstijl
NSLayoutConstraint.constraintsWithVisualFormat("H:[myViewKey(200)]", options: [], metrics: nil, views: ["myViewKey": myView])
NSLayoutConstraint.constraintsWithVisualFormat("V:[myViewKey(100)]", options: [], metrics: nil, views: ["myViewKey": myView])
Midden in container
Ankerstijl
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
Visueel formaat Taalstijl
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])
Hoe Auto Layout te gebruiken
Automatische lay-out wordt gebruikt om weergaven te ordenen zodat ze er op elk apparaat en in elke oriëntatie goed uitzien. Beperkingen zijn de regels die aangeven hoe alles moet worden vastgelegd. Ze omvatten onder andere het vastzetten van randen, centreren en instellen van formaten.
Automatische lay-out is standaard ingeschakeld, maar u kunt dit nog een keer controleren. Als u op Main.storyboard in de Project Navigator klikt en vervolgens de Bestandscontrole toont. Zorg dat Auto Layout en Size Classes zijn aangevinkt:
Automatische opmaakbeperkingen kunnen worden ingesteld in de Interface Builder of in code. In de Interface Builder vindt u de Auto Layout-tools rechts onderaan. Als u hierop klikt, ziet u verschillende opties voor het instellen van de beperkingen voor een weergave.
Als u verschillende beperkingen wilt hebben voor verschillende apparaatgroottes of -richtingen, kunt u deze instellen in de opties wAny hAny Size Class in het midden onderaan.
Centerbeperkingen
Selecteer uw knop (of welke weergave u ook wilt centreren) op het storyboard . Klik vervolgens rechtsonder op de uitlijnknop. Selecteer Horizontally in Container
en Vertically in Container
. Klik op "2 beperkingen toevoegen".
Als het nog niet perfect gecentreerd was, moet je misschien nog een ding doen. Klik op de knop "Frames bijwerken" die zich links van de knop "Inbedden in stapel" op de onderste balk bevindt.
U kunt ook "frames bijwerken indien nodig" door op ⌘ + ⌥ + = (Command + Option en is gelijk aan) te drukken na het selecteren van de weergave, dit kan wat tijd besparen.
Wanneer u uw app nu uitvoert, moet deze gecentreerd zijn, ongeacht de apparaatgrootte die u gebruikt.
Een andere manier om weergaven te centreren met Interface Builder is door te klikken en te slepen. Stel dat u een UILabel
in een weergave wilt centreren. Open de Document Outline
in uw storyboard door linksonder op de zijbalkknop te klikken. Klik en sleep van het label naar de weergave terwijl u Ctrl (besturingselement) ingedrukt houdt. Er zou een blauwe lijn moeten verschijnen:
Na vrijgave verschijnt een menu met beperkingsopties:
Selecteer "Horizontaal centreren in container" en "Verticaal centreren in container". Werk frames indien nodig bij en voila! Een gecentreerd label.
Als alternatief kunt u de beperkingen programmatisch toevoegen. Maak de beperkingen en voeg ze toe aan de gewenste UI-elementen en -weergaven zoals in het volgende voorbeeld wordt beschreven, waarbij we een knop maken en deze in het midden, horizontaal en verticaal uitlijnen op de supervisie:
Doelstelling 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
}
Snel
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])
}
Gelijkmatig bekeken ruimte
Het is gebruikelijk dat twee weergaven naast elkaar staan, gecentreerd in hun supervisie. Het algemene antwoord op Stack Overflow is om deze twee weergaven in een UIView
en de UIView
centreren. Dit is niet noodzakelijk of aanbevolen. Uit de UILayoutGuide- documenten:
Er zijn een aantal kosten verbonden aan het toevoegen van dummyweergaven aan uw weergavehiërarchie. Ten eerste zijn er de kosten van het creëren en onderhouden van het uitzicht zelf. Ten tweede is de dummyweergave volledig lid van de weergavehiërarchie, wat betekent dat deze overhead toevoegt aan elke taak die de hiërarchie uitvoert. Het ergste van alles is dat de onzichtbare dummyweergave berichten kan onderscheppen die bedoeld zijn voor andere weergaven, waardoor problemen ontstaan die heel moeilijk te vinden zijn.
U kunt UILayoutGuide
gebruiken om dit te doen, in plaats van de knoppen toe te voegen aan een onnodige UIView
. Een UILayoutGuide
is in wezen een rechthoekige ruimte die kan samenwerken met Auto Layout. U plaatst een UILayoutGuide
aan de linker- en rechterkant van de knoppen en stelt hun breedte gelijk in. Hiermee worden de knoppen gecentreerd. Hier is hoe het te doen in code:
Visueel formaat Taalstijl
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
Ankerstijl
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
Je zult hier ook verticale beperkingen aan moeten toevoegen, maar dit zal de knoppen in het beeld centreren zonder "dummy" aanzichten toe te voegen! Dit bespaart het systeem CPU-tijd te verspillen door die "dummy" -weergaven weer te geven. In dit voorbeeld worden knoppen gebruikt, maar u kunt knoppen uitwisselen voor elke weergave waarvoor u beperkingen wilt instellen.
Als u iOS 8 of eerder ondersteunt, is de eenvoudigste manier om deze lay-out te maken, verborgen dummy-weergaven toe te voegen. Met iOS 9 kunt u dummy-weergaven vervangen door lay-outgidsen.
Opmerking: Interface Builder ondersteunt nog geen lay-outgidsen (Xcode 7.2.1). Dus als u ze wilt gebruiken, moet u uw beperkingen in code maken. Bron .
UILabel intrinsieke grootte
We moeten een weergave maken met een afbeeldingsvoorvoegsel voor een tekst. tekst kan een variabele lengte hebben. We moeten een resultaat bereiken waarbij tekst in Afbeelding + altijd in het midden van een bovenaanzicht staat.
Stap 1: Maak eerst een project met één weergave en noem het naar keuze en open de eerste weergave van het storyboard. Sleep een weergave met een redelijke grootte en stel de achtergrondkleur in op geel. Ik heb mijn viewcontroller verkleind naar 3,5 ". Het resultaat weergave zou er ongeveer zo uit moeten zien
Stap 2: Nu voegen we beperkingen toe aan de gele weergave. Om te beginnen voegen we breedte- en hoogtebeperkingen toe (wacht even, hebben we niet gezegd dat die weergave dynamische breedte zal hebben? Ok, we komen er later op terug) Voeg de volgende beperkingen volgens de onderstaande afbeelding storen de breedtewaarde niet, elke waarde is prima voor de breedte, houd deze gewoon groot genoeg zodat we autolayouts correct kunnen toevoegen.
Na het toevoegen van deze twee beperkingen zul je zien dat XCode je fouten geeft zoals in onderstaande afbeelding ze laat zien en begrijpen.
We hebben twee fouten (rood betekent fout). Zoals hierboven besproken, laten we het dubbelzinnigheidgedeelte opnieuw bekijken
Ontbrekende beperkingen: Noodzaak van beperkingen voor: X-positie: - Zoals hierboven besproken, hebben we de weergave een breedte en een hoogte gegeven zodat de "BOUNDS" is gedefinieerd, maar we hebben de oorsprong niet opgegeven zodat de "FRAME" niet is gedefinieerd. Autolayout kan niet bepalen wat de X-positie van onze gele weergave zal zijn
Ontbrekende beperkingen: Noodzaak van beperkingen voor: Y-positie: - Zoals hierboven besproken, hebben we de weergave een breedte en een hoogte gegeven zodat de "BOUNDS" is gedefinieerd, maar we hebben de oorsprong niet opgegeven zodat de "FRAME" niet is gedefinieerd. Autolayout kan niet bepalen wat de Y-positie van onze gele weergave zal zijn. Om dit op te lossen, moeten we autolayout iets geven om X en Y te resoleren. Omdat we geen frames kunnen instellen, doen we het op autolayout. Voeg de volgende beperkingen toe volgens de afbeelding hieronder zal ik het later uitleggen
Wat we hebben gedaan is, we hebben een "Verticaal midden" en "Horizontaal midden" toegevoegd, deze beperking vertelt autolayout dat onze gele weergave altijd horizontaal in het midden zal zijn: dus X in bepaald hetzelfde is met verticale beperking en Y wordt bepaald. (U moet mogelijk het kader aanpassen).
Stap 3: Inmiddels is onze basisgele weergave klaar. We voegen de prefixafbeelding toe als subweergave van onze gele weergave met de volgende beperkingen. U kunt elke gewenste afbeelding kiezen.
Omdat we een vaste dimensie hebben voor onze prefixafbeelding, hebben we een vaste breedtehoogte voor deze afbeelding. Voeg de beperkingen toe en ga door naar de volgende stap.
Stap 4: Voeg een UILabel toe als de subweergave van onze gele weergave en voeg de volgende beperkingen toe
Zoals je kunt zien, heb ik alleen relatieve beperkingen aan onze UILabel gegeven. Het is 8 punten van het voorvoegsel en 0,0,0 bovenaan bovenaan en onderaan van de gele weergave. Omdat we willen dat de breedte dynamisch is, geven we geen breedte- of hoogtebeperkingen. .
Vraag: Waarom krijgen we nu geen fouten, hebben we geen breedte en hoogte gegeven? Ans: - We krijgen alleen een fout of waarschuwing als de automatische lay-out niets kan oplossen wat nodig is om een weergave op het scherm weer te geven. Of het nu breedte of oorsprong is. Omdat ons label relatief is aan de gele weergave en het voorvoegsel van de afbeelding en hun frames is goed gedefinieerd. Autolayout kan het frame van ons label berekenen.
Stap 5: Als we ons herinneren, zullen we ons realiseren dat we een vaste weergave hebben gegeven aan de gele weergave, maar we willen dat deze dynamisch is, afhankelijk van de tekst van ons label. Dus we zullen onze breedte-beperking van de gele weergave aanpassen. Breedte van de gele weergave is noodzakelijk om dubbelzinnigheid op te lossen, maar we willen dat het tijdens runtime wordt opgeheven op basis van de inhoud van UILabel. Dus zullen we onze gele weergave selecteren en naar Grootte-infovenster gaan en de prioriteit van breedtebeperking verminderen tot 1, zodat deze overheerst wordt. Volg de onderstaande afbeelding.
Stap 6: We willen dat UILabel uitbreidt volgens tekst en onze gele weergave pusht. Dus we hebben de prioriteit van de gele weergavebreedte verlaagd. Nu zullen we de prioriteit van tekstcompressieweerstand van onze UILabel verhogen. We willen dat onze weergave vermindert als dus we zullen de prioriteit van inhoud knuffelen van UILabel verhogen. Volg de afbeelding hieronder
Zoals u kunt zien, hebben we de prioriteit voor inhoud knuffelen verhoogd tot 500 en de prioriteit voor compressieweerstand tot 751, die met succes de prioriteit 1 van de breedtebeperking zal overschrijden.
Nu bouwen en uitvoeren ziet u iets als volgt.
Animeren met Auto Layout
Zonder Auto Layout is animatie volbracht door het frame van een weergave in de loop van de tijd te veranderen. Met Auto Layout dicteren de beperkingen het weergaveframe, dus u moet in plaats daarvan de beperkingen animeren. Deze aanduiding maakt animatie moeilijker te visualiseren.
Dit zijn de manieren om te animeren met Auto Layout:
- Wijzig de constante van de beperking na het maken met behulp van periodieke aanroepen (
CADisplayLink
,dispatch_source_t
,dispatch_after
,NSTimer
).layoutIfNeeded
vervolgenslayoutIfNeeded
aan om de beperking bij te werken. Voorbeeld:
Doelstelling C:
self.someConstraint.constant = 10.0;
[UIView animateWithDuration:0.25 animations:^{
[self.view layoutIfNeeded];
}];
Snel:
self.someConstraint.constant = 10.0
UIView.animate(withDuration: 0.25, animations: self.view.layoutIfNeeded)
- Wijzig de beperkingen en roep
[view layoutIfNeeded]
in een animatieblok. Dit interpoleert tussen de twee posities en negeert beperkingen tijdens de animatie.
[UIView animateWithDuration:0.5 animations:^{
[view layoutIfNeeded];
}]
Wijzig de prioriteit van de beperkingen . Dit is minder CPU-intensief dan het toevoegen en verwijderen van beperkingen.
Verwijder alle beperkingen en gebruik autosizing-maskers . Voor later moet u
view.translatesAutoresizingMaskIntoConstraints = YES
.Gebruik beperkingen die de bedoelde animatie niet hinderen .
Gebruik een containerweergave . Positioneer de supervisie met behulp van beperkingen. Voeg vervolgens een subweergave toe met beperkingen die de animatie niet bestrijden, bijvoorbeeld: een centrum ten opzichte van de superview. Hiermee worden een deel van de beperkingen van de supervisie verwijderd, zodat ze niet vechten tegen de animatie in de subweergave.
Animeer lagen in plaats daarvan . Laagtransformaties activeren de Auto Layout niet.
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];
Lay-out onderdrukken . Roep
[super layoutSubviews]
en[super layoutSubviews]
de beperkingen.Wijzig het frame in viewDidLayoutSubviews . Auto Layout wordt toegepast in
layoutSubviews
, dus verander het eenmaal inviewDidLayoutSubviews
.Afmelden voor Auto Layout en handmatig instellen van weergaven. U kunt deze dwingende
layout
layoutSubviews
/layout
zonder de implementatie van de superklasse aan te roepen.
Snelle tip: als het bovenliggende layoutIfNeeded()
van de geanimeerde weergave niet wordt geïnterpoleerd (dat wil zeggen dat de animatie van de begin- tot eindstatus springt), roept u layoutIfNeeded()
in de diepste weergave die de bovenliggende is van de weergave die is geanimeerd (met andere woorden , dat wordt niet beïnvloed door de animatie). Ik weet niet precies waarom dit werkt.
UILabel Priority Conflict oplossen
Probleem : wanneer u veel labels in een weergave gebruikt, krijgt u mogelijk een waarschuwing :
Hoe kunnen we deze waarschuwing oplossen?
Oplossing : we berekenen en stellen de prioriteiten in volgorde. De prioriteiten moeten verschillen van labels. Het betekent dat wat belangrijk is, een hogere prioriteit krijgt. In mijn geval stel ik bijvoorbeeld de verticale prioriteiten voor mijn labels er als volgt uit:
Ik heb de hoogste prioriteit ingesteld voor het 1e label en de laagste voor het 4e label.
In een ViewController denk ik dat je moeilijk het effect van die prioriteiten kunt zien. Het is echter heel duidelijk met UITableViewCell + schatting celhoogte.
Hoop dat dit helpt.
UILabel & Parentview-formaat volgens tekst in UILabel
Stapsgewijze handleiding: -
Stap 1: - Stel beperking in op UIView
- Leidend. 2) Boven. 3) Trailing. (Vanuit hoofdweergave)
Stap 2: - Stel beperking in op Label 1
- Toonaangevende 2) Top 3) Trailing (vanuit zijn superview)
Stap 3: - Stel beperking in op Label 2
- Toonaangevende 2) Top 3) Trailing (vanuit de superview)
Stap 4: - Meest lastig geef een bodem aan UILabel van UIView.
Stap 5: - (Optioneel) Stel beperking in op UIButton
- Vooraan 2) Onderaan 3) Achteraan 4) Vaste hoogte (vanuit hoofdweergave)
Uitgang: -
Opmerking: - Zorg ervoor dat u Aantal regels = 0 hebt ingesteld in de eigenschap Label.
Ik hoop dat deze informatie genoeg is om Autoresize UIView te begrijpen op basis van de lengte van UILabel en Autoresize UILabel volgens tekst.
Visueel formaat Taalbeginselen: beperkingen in code!
HVFL is een taal die is ontworpen om UI-elementen op een eenvoudige en snelle manier te beperken. Over het algemeen heeft VFL een voordeel ten opzichte van traditionele UI-aanpassingen in de Interface Builder omdat het veel leesbaarder, toegankelijker en compacter is.
Hier is een voorbeeld van VFL, waarin drie UIViews van links naar rechts worden beperkt, waardoor superView.width
wordt aGradeView
met aGradeView
"H:|[bgView][aGradeView(40)][bGradeView(40)]|"
Er zijn twee assen waarin we UI-objecten kunnen beperken, horizontaal en verticaal.
Elke regel van VFL begint altijd met H:
of V:
Als geen van beide aanwezig is, is de standaardoptie H:
We hebben een pijplijn. |
Dit symbool, of de pijp, verwijst naar de superview. Als u het fragment van de VFL-code hierboven goed bekijkt, ziet u twee van deze pijpleidingen.
Dit betekent de twee horizontale uiteinden van de superview, de buitenste en buitenste grenzen van het recht.
Vervolgens ziet u enkele vierkante haken, binnen de eerste set vierkante haken hebben we bgView
. Als we vierkante haken hebben, verwijst dit naar een UI-element. Nu vraagt u zich misschien af hoe we een verband leggen tussen de naam en het daadwerkelijke UI-element, een outlet misschien?
Ik zal dat behandelen aan het einde van de post.
Als je naar het tweede paar vierkante haakjes [aGradeView(50)]
, hebben we ook enkele haakjes erin ingekapseld, wanneer dat aanwezig is, bepaalt dit de breedte / hoogte afhankelijk van de assen, die in dit geval 50 is pixels in breedte.
De eerste vierkante haken [bgView]
hadden geen expliciet gedefinieerde breedte, wat betekent dat deze zo ver mogelijk uitsteekt.
Oke, dat is het voor de basis, meer over de geavanceerde dingen in een ander voorbeeld.
// 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];
Gemengd gebruik van Auto Layout met niet-Auto Layout
Soms wilt u misschien een aantal extra acties uitvoeren op berekeningen van Auto Layout die door UIKit
zelf zijn uitgevoerd.
Voorbeeld: wanneer u een UIView
heeft die een maskLayer
, moet u mogelijk maskLayer
bijwerken zodra Auto Layout het frame
UIView
verandert
// 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;
...
}
of als u extra actie wilt ondernemen voor Auto Layout in ViewController
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
// now you can assume all your subviews are positioned/resized correctly
self.customView.frame = self.containerView.frame;
}
Proportionele indeling
Beperking gemaakt als
NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1.0, constant: 20.0)
of, vanuit wiskundig oogpunt:
view.attribute * multiplier + constant (1)
U kunt de multiplier gebruiken om een proportionele lay-out voor verschillende groottefactoren te maken.
Voorbeeld:
Turquoise View (V1) is een vierkant met breedte proportionele superview-breedte met verhouding 1: 1.1
Gary square (V2) is een deelweergave van V1. Bodemruimte ingesteld door constante = 60, volgruimte ingesteld door vermenigvuldiger = 1.125 en constante = 0
Trailing space proportioneel ingesteld, bottom space ingesteld als een constante.
Opmerking: als view.attribute gelijk is aan 0 (bijvoorbeeld voorloopspatie), is beperkingsformule (1) gelijk aan 0. U moet het tweede beperkingsitem wijzigen of beperking instellen ten opzichte van de marge, om view.attribute! = 0.
NSLayoutConstraint: contraints in code!
Wanneer we aan een framework werken, als de beperkingen niet te complex zijn, kunnen we beter Interface Builder of NSLayoutConstraint in code gebruiken om het kleiner genoeg te maken, in plaats van Masonry of SnapKit te importeren.
- Doelstelling 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];