autolayoutAan de slag met autolayout


Opmerkingen

Auto Layout berekent dynamisch de grootte en positie van alle weergaven in uw weergavehiërarchie, op basis van beperkingen die door deze weergaven worden geplaatst - door Apple. Auto lay-out kan ook worden begrepen door het te beschrijven als een set regels die u gebruikt voor elk van de weergaven in uw weergavehiërarchie, welke regel definieerde hoe de uitlijning en inkrimping of uitbreiding van de weergave wordt uitgevoerd volgens verschillende schermformaten van apparaten.

We moeten Auto Layout gebruiken in al onze projecten, omdat dit ons helpt bij het beheren van het ontwerp van de schermen voor alle beschikbare apparaten waarop we ons richten. Hiervoor moeten we gewoon begrijpen wat het is en hoe het presteert. Nadat we begrepen hebben hoe het werkt, is een dynamische lay-out voor meerdere apparaten leuk.

Een UIImageView toevoegen aan het midden van het scherm

Als u een UIImageView wilt toevoegen aan het midden van het scherm met een breedte en hoogte van 100 pixels, moet u de x-beperking in het midden en de y-beperking in het midden van de supervisie instellen vanuit de UIImageView en de breedte-, hoogtebeperking aan de UIIMageView. Hier is de code. Er is een manier om dit in storyboard te doen, maar ik heb in code geschreven omdat het begrijpelijk is voor deze situatie in documentatie.

UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 100.0, 100.0);
imageView.self.translatesAutoresizingMaskIntoConstraints = NO;

[imageView addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:100.0]];
[imageView addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:100.0]];
[superview addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0]];
[superview addConstraint:[NSLayoutConstraint constraintWithItem:imageView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0]];
 

Installatie of instellingen

Om automatische lay-out te gebruiken, moeten we een Booleaanse vlag in het storyboard inschakelen. Het wordt getoond in de onderstaande afbeelding. Hierna kunnen we de automatische lay-out in ons storyboard gebruiken. Er is een andere optie als we grootteklassen willen gebruiken of niet. De grootteklasse is ook een handige optie in de automatische lay-out die ons helpt om verschillende schermformaten voor apparaten verschillend te ontwerpen met dezelfde of verschillende elementen. De afbeelding voor de installatie komt hier. Het is van het bestandsinspectiepaneel van de eigenschappeneditor in Xcode.

voer hier de afbeeldingsbeschrijving in

Visuele opmaaktaal gebruiken

Er is een manier om het definiëren van autolayout voor weergaven met VFL te vereenvoudigen. In het begin lijkt het misschien moeilijk, maar het is eigenlijk heel gemakkelijk te gebruiken. Enkele definities eerst:

  • | vertegenwoordigt superview
  • H: of V: vertegenwoordigen de huidige oriëntatie - horizontaal of verticaal
  • weergavenamen moeten tussen vierkante haken staan
  • kijkhoogte en breedte moeten tussen haakjes staan
  • marges worden gespecificeerd tussen aanzichten en omgeven door koppeltekens
  • prioriteit voor een marge of weergavegrootte kan worden opgegeven met @

Voorbeelden van syntaxis van het visuele formaat

  1. someView is zonder marges aan de linker- en rechterrand van de superview bevestigd:

    H:|[someView]|
     
  2. someView is bovenaan bevestigd met een marge van 10 punten en heeft een hoogte die gelijk is aan value :

    V:|-(10)-[someView(value)]
     
  3. someView1 en someView2 hebben twee marges daartussen gedefinieerd - value1 met een prioriteit van 900 en value2 met een prioriteit van 800:

    H:[someView1]-(value1@900, value2@800)-[someView2]
     
  4. someView1 hoogte is gelijk aan hoogte van someView2 :

    V:[someView1(==someView2)]
     

Code voorbeeld

Voorbeeld van aangepaste weergave

Laten we een nieuwe weergave definiëren, met een tekstveld en twee knoppen met gelijke hoogten met marges ertussen, en een label hieronder. De knoppen moeten gelijke breedte hebben en het label moet overlopen naar de volgende regel als de inhoud lang genoeg is. Deze weergave moet automatisch worden aangepast aan de inhoud op zowel horizontale als verticale as en gecentreerd in het midden van de supervisie.

- (void)addView {

    // first lets define a container for our views
    UIView *container = [UIView new];
    // do not forget to disable autoresizing masks for autolayout views
    container.translatesAutoresizingMaskIntoConstraints = NO;
    container.backgroundColor = [UIColor grayColor];
    
    // now to the subviews. this is mostly boilerplate code:
    UITextField *textField = [UITextField new];
    textField.translatesAutoresizingMaskIntoConstraints = NO;
    textField.borderStyle = UITextBorderStyleRoundedRect;

    UIButton *button1 = [UIButton buttonWithType:UIButtonTypeSystem];
    button1.translatesAutoresizingMaskIntoConstraints = NO;
    [button1 setTitle:@"Send" forState:UIControlStateNormal];

    UIButton *button2 = [UIButton buttonWithType:UIButtonTypeSystem];
    button2.translatesAutoresizingMaskIntoConstraints = NO;
    [button2 setTitle:@"Cancel" forState:UIControlStateNormal];

    UILabel *label = [UILabel new];
    label.translatesAutoresizingMaskIntoConstraints = NO;
    // this line tells the label to let the text overflow to the next line if needed
    label.numberOfLines = 0;
    label.text = @"This label has relatively long text, that should take two lines.";
    
    // before adding any constraints the views should be present in the hierarchy
    [container addSubview:textField];
    [container addSubview:button1];
    [container addSubview:button2];
    [container addSubview:label];
    
    // now lets define two helper dictionaries, one for metrics of our view:
    NSDictionary *metrics = @{@"margin": @10, @"textFieldWidth": @160, @"buttonWidth": @44};
    // and the other for view bindings using a handy macro, which effectively creates a dictionary with variables of the same name:
    NSDictionary *bindings = NSDictionaryOfVariableBindings(textField, button1, button2, label);
    // lets define a horizontal format for the first row of views in a variable:
    NSString *horizontalFormat = @"H:|-(margin)-[textField(textFieldWidth)]-(margin)-[button1(==button2)]-(margin)-[button2]-(margin)-|";
    // this format defines margins of equal size between all views, fixed width for the textField and sets both buttons to have equal widths
    // lets add these constraints to our container:
    [container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:horizontalFormat options:0 metrics:metrics views:bindings]];
    // now lets define horizontal constraints for the second row, where we have the label:
    [container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(margin)-[label]-(margin)-|" options:0 metrics:metrics views:bindings]];
    // another relatively long visual format string:
    NSString *verticalFormat = @"V:|-(margin)-[textField]-(margin)-[label]-(margin)-|";
    // this format string defines vertical constraints for textField and label, and should also define the height of the container
    // adding these constraints to the container view:
    [container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:verticalFormat options:0 metrics:metrics views:bindings]];
    // what we have left are constraints for vertical positions of the buttons
    // lets attach them to the top of the container with a margin:
    [container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(margin)-[button1]" options:0 metrics:metrics views:bindings]];
    [container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(margin)-[button2]" options:0 metrics:metrics views:bindings]];
    
    // the container is all set up, adding it to the superview:
    [self.view addSubview:container];
    
    // now lets position our container in its superview
    // you can not use dot notation in the bindings macro, so lets define a temp variable for the superview:
    UIView *superview = self.view;
    
    // positioning a view in the center of its superview is not so straightforward
    // we will use a trick from this answer: http://stackoverflow.com/a/14917695/934710
    NSDictionary *containerBindings = NSDictionaryOfVariableBindings(superview, container);
    // width constraint from horizontal format is not part of the trick, but is necessary to constrain container width
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[superview]-(<=1)-[container(<=superview)]" options:NSLayoutFormatAlignAllCenterY metrics:nil views:containerBindings]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[superview]-(<=1)-[container]" options:NSLayoutFormatAlignAllCenterX metrics:nil views:containerBindings]];

}