Szukaj…


Wprowadzenie

Auto układ dynamicznie oblicza rozmiar i położenie wszystkich widoków w hierarchii widoków, w oparciu o ograniczenia nałożone na te widoki. Źródło

Składnia

  • NSLayoutConstraint (item: Any, atrybut: NSLayoutAttribute, relatedBy: NSLayoutRelation, toItem: Any ?, atrybut: NSLayoutAttribute, mnożnik: CGFloat, stała: CGFloat) // Utwórz programowo ograniczenie

Programowe ustawianie ograniczeń

Przykład kodu płyty kotłowej

override func viewDidLoad() {
    super.viewDidLoad()

    let myView = UIView()
    myView.backgroundColor = UIColor.blueColor()
    myView.translatesAutoresizingMaskIntoConstraints = false
    view.addSubview(myView)

    // Add constraints code here
    // ...
}

W poniższych przykładach styl kotwicy jest preferowaną metodą w NSLayoutConstraint stylu NSLayoutConstraint , jednak jest on dostępny tylko w systemie iOS 9, więc jeśli obsługujesz system iOS 8, nadal powinieneś używać stylu NSLayoutConstraint .

Przypinanie

Styl kotwicy

let margins = view.layoutMarginsGuide
myView.leadingAnchor.constraintEqualToAnchor(margins.leadingAnchor, constant: 20).active = true
  • Oprócz leadingAnchor istnieje także trailingAnchor , topAnchor i bottomAnchor .

Styl NSLayoutConstraint

NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1.0, constant: 20.0).active = true
  • Oprócz .Leading istnieje również .Trailing , .Top i .Bottom .
  • Oprócz .LeadingMargin istnieją również .TrailingMargin , .TopMargin i .BottomMargin .

Styl języka formatu wizualnego

NSLayoutConstraint.constraintsWithVisualFormat("H:|-20-[myViewKey]", options: [], metrics: nil, views: ["myViewKey": myView])

Szerokość i wysokość

Styl kotwicy

myView.widthAnchor.constraintEqualToAnchor(nil, constant: 200).active = true
myView.heightAnchor.constraintEqualToAnchor(nil, constant: 100).active = true

Styl NSLayoutConstraint

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

Styl języka formatu wizualnego

NSLayoutConstraint.constraintsWithVisualFormat("H:[myViewKey(200)]", options: [], metrics: nil, views: ["myViewKey": myView])
NSLayoutConstraint.constraintsWithVisualFormat("V:[myViewKey(100)]", options: [], metrics: nil, views: ["myViewKey": myView])

Centrum w pojemniku

Styl kotwicy

myView.centerXAnchor.constraintEqualToAnchor(view.centerXAnchor).active = true
myView.centerYAnchor.constraintEqualToAnchor(view.centerYAnchor).active = true

Styl NSLayoutConstraint

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

Styl języka formatu wizualnego

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])

Jak korzystać z automatycznego układu

Automatyczny układ służy do rozmieszczania widoków tak, aby wyglądały dobrze na dowolnym urządzeniu i orientacji. Ograniczenia to zasady, które mówią, jak wszystko należy ułożyć. Obejmują one między innymi przypinanie krawędzi, centrowanie i ustawianie rozmiarów.

Automatyczny układ jest domyślnie włączony, ale możesz to dwukrotnie sprawdzić. Jeśli klikniesz Main.storyboard w Nawigatorze projektu, a następnie wyświetlisz Inspektora plików. Upewnij się, że zaznaczono opcję Automatyczny układ i klasy wielkości:

wprowadź opis zdjęcia tutaj

Automatyczne ograniczenia układu można ustawić w Konstruktorze interfejsów lub w kodzie. W Konstruktorze interfejsów znajdziesz narzędzia Auto Layout w prawym dolnym rogu. Kliknięcie ich ujawni różne opcje ustawiania ograniczeń w widoku.

wprowadź opis zdjęcia tutaj

Jeśli chcesz mieć różne ograniczenia dla różnych rozmiarów urządzeń lub orientacji, możesz ustawić je w KAŻDEJ opcji klasy rozmiaru znajdującej się w dolnej środkowej części.

wprowadź opis zdjęcia tutaj

Ograniczenia środkowe

Wybierz przycisk (lub dowolny widok, który chcesz wyśrodkować) w serii ujęć . Następnie kliknij przycisk wyrównywania w prawym dolnym rogu. Wybierz Horizontally in Container i Vertically in Container . Kliknij „Dodaj 2 ograniczenia”.

Wyrównanie - metoda 1

Jeśli nie było już idealnie wyśrodkowane, być może trzeba zrobić jeszcze jedną rzecz. Kliknij przycisk „Aktualizuj ramki”, który znajduje się dwa po lewej stronie przycisku „Osadź w stosie” na dolnym pasku. Zaktualizuj ramki

Możesz także „zaktualizować ramki w razie potrzeby”, naciskając jednocześnie + + = (Command + Opcja i równa się) po wybraniu widoku, może to zaoszczędzić trochę czasu.

Teraz po uruchomieniu aplikacja powinna być wyśrodkowana, bez względu na używany rozmiar urządzenia.

Innym sposobem na wyśrodkowanie widoków za pomocą Konstruktora interfejsów jest przeciągnięcie z wciśniętym klawiszem Control. Powiedz, że chcesz wyśrodkować UILabel w widoku. Otwórz Document Outline w serii ujęć, klikając przycisk paska bocznego w lewym dolnym rogu. Kliknij i przeciągnij z etykiety do widoku, trzymając wciśnięty klawisz Ctrl (Control), a powinna pojawić się niebieska linia:

niebieska Linia

Po wydaniu pojawi się menu opcji ograniczeń:

menu opcji wiązań

Wybierz „Wyśrodkuj poziomo w pojemniku” i „Wyśrodkuj pionowo w pojemniku”. Zaktualizuj ramki w razie potrzeby i voila! Wyśrodkowana etykieta.

Alternatywnie możesz dodać ograniczenia programowo. Utwórz wiązania i dodaj je do pożądanych elementów interfejsu użytkownika i widoków, jak opisano w poniższym przykładzie, w którym tworzymy przycisk i wyrównujemy go w środku, poziomo i pionowo do jego widoku:

Cel 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
}

Szybki

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])
}

Widoki kosmiczne równomiernie

wprowadź opis zdjęcia tutaj

Często chce się, aby dwa widoki były obok siebie, wyśrodkowane w ich superwizji. Częstą odpowiedzią na przepełnienie stosu jest osadzenie tych dwóch widoków w UIView i wyśrodkowanie UIView . Nie jest to konieczne ani zalecane. Z dokumentów UILayoutGuide :

Istnieje wiele kosztów związanych z dodawaniem widoków zastępczych do hierarchii widoków. Po pierwsze, istnieje koszt utworzenia i utrzymania samego widoku. Po drugie, widok fikcyjny jest pełnym elementem hierarchii widoków, co oznacza, że dodaje narzut do każdego zadania wykonywanego przez hierarchię. Co najgorsze, niewidoczny widok fikcyjny może przechwytywać wiadomości przeznaczone dla innych widoków, powodując problemy, które są bardzo trudne do znalezienia.

UILayoutGuide to zrobić, możesz użyć UILayoutGuide , zamiast dodawać przyciski do niepotrzebnego UIView . UILayoutGuide to zasadniczo prostokątna przestrzeń, która może wchodzić w interakcje z UILayoutGuide automatycznym. Umieszczasz UILayoutGuide po lewej i prawej stronie przycisków i ustawiasz ich szerokość na równe. Spowoduje to wyśrodkowanie przycisków. Oto jak to zrobić w kodzie:

Styl języka formatu wizualnego

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

Styl kotwicy

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

Trzeba będzie również dodać ograniczenia pionowe, ale spowoduje to wyśrodkowanie przycisków w widoku bez dodawania żadnych „fałszywych” widoków! Pozwoli to zaoszczędzić systemowi na marnowaniu czasu procesora na wyświetlanie tych „fałszywych” widoków. W tym przykładzie użyto przycisków, ale możesz zamienić przyciski dla dowolnego widoku, na którym chcesz nałożyć ograniczenia.

Jeśli obsługujesz system iOS 8 lub wcześniejszy, najłatwiejszym sposobem utworzenia tego układu jest dodanie ukrytych widoków obojętnych. W systemie iOS 9 można zastąpić atrapy widoków przewodnikami układu.

Uwaga: Konstruktor interfejsów nie obsługuje jeszcze przewodników układu (Xcode 7.2.1). Więc jeśli chcesz ich użyć, musisz utworzyć ograniczenia w kodzie. Źródło

Rozmiar wewnętrzny UILabel

Musimy stworzyć widok, który będzie miał prefiks obrazu do tekstu. tekst może mieć różną długość. Musimy osiągnąć wynik, w którym w Obrazie + tekst zawsze znajduje się w środku widoku rodzica.

wprowadź opis zdjęcia tutaj

Krok 1: Najpierw utwórz projekt pojedynczego widoku i nazwij go wybranym przez siebie wyborem i otwórz widok pięści na tablicy opowieści. Przeciągnij widok o rozsądnym rozmiarze i ustaw kolor tła na żółty. Zmieniłem rozmiar mojego kontrolera widoku na 3,5 ″. widok powinien wyglądać mniej więcej tak

wprowadź opis zdjęcia tutaj

Krok 2: Teraz dodamy ograniczenia do żółtego widoku. Na początek dodamy ograniczenia szerokości i wysokości (Chwileczkę, czy nie powiedzieliśmy, że widok będzie miał dynamiczną szerokość? Ok, wrócimy do niego później) Dodaj następujące ograniczenia, jak na poniższym obrazku, nie zawracają sobie głowy wartością szerokości, każda wartość będzie w porządku dla szerokości, po prostu utrzymaj ją na tyle dużą, abyśmy mogli poprawnie dodać automatyczne układanie.

wprowadź opis zdjęcia tutaj

Po dodaniu tych dwóch ograniczeń zobaczysz, że XCode daje ci błędy, jak na poniższym obrazku pozwala je zobaczyć i zrozumieć. wprowadź opis zdjęcia tutaj

Mamy dwa błędy (czerwony oznacza błąd) Jak omówiono powyżej, powróćmy do części niejednoznaczności

Brakujące ograniczenia: Potrzebne ograniczenia dla: Pozycja X: - Jak omówiono powyżej, nadaliśmy widokowi szerokość i wysokość, więc zdefiniowano jego „BOUNDS”, ale nie podaliśmy jego pochodzenia, więc jego „RAMKA” nie jest zdefiniowana. Autolayout nie jest w stanie określić, jaka będzie pozycja X naszego żółtego widoku

Brakujące ograniczenia: Potrzebne ograniczenia dla: Pozycja Y: - Jak omówiono powyżej, nadaliśmy widokowi szerokość i wysokość, więc zdefiniowano jego „BOUNDS”, ale nie podaliśmy jego pochodzenia, więc jego „RAMKA” nie jest zdefiniowana. Autolayout nie jest w stanie określić, jaka będzie pozycja Y naszego żółtego widoku Aby rozwiązać ten problem, musimy dać autoukładowi coś do zmiany X i Y. Ponieważ nie możemy ustawić ramek, zrobimy to w sposób autoukładu. Dodaj następujące ograniczenia zgodnie z zdjęcie podane poniżej wyjaśnię to później

wprowadź opis zdjęcia tutaj

To, co zrobiliśmy, dodaliśmy „Środek pionowy” i „Środek poziomy”, które to ograniczenie mówią autoukładowi, że nasz żółty widok będzie zawsze w środku Poziomo: więc X w określonym to samo jest z ograniczeniem pionowym, a Y jest określone. może być konieczne dostosowanie ramki).

Krok 3: Nasz podstawowy żółty widok jest już gotowy. Dodamy obraz prefiksu jako widok podrzędny naszego żółtego widoku z następującymi ograniczeniami. Możesz wybrać dowolny obraz do wyboru.

wprowadź opis zdjęcia tutaj

Ponieważ mamy ustalony wymiar dla naszego obrazu prefiksu, będziemy mieć stałą wysokość dla tego podglądu obrazu. Dodaj ograniczenia i przejdź do następnego kroku.

Krok 4: Dodaj UILabel jako widok podrzędny naszego żółtego widoku i dodaj następujące ograniczenia

wprowadź opis zdjęcia tutaj

Jak widać, podałem tylko względne ograniczenia naszemu UILabel. 8 punktów z obrazka prefiksu i 0,0,0 górna część dolna i dolna z widoku żółtego. Ponieważ chcemy, aby szerokość była dynamiczna, nie będziemy ograniczać szerokości ani wysokości .

P: Dlaczego nie otrzymujemy teraz żadnych błędów, nie podaliśmy żadnej szerokości i wysokości? Odp .: - Pojawia się błąd lub ostrzeżenie tylko wtedy, gdy układ automatyczny nie jest w stanie rozwiązać niczego, co jest konieczne do renderowania widoku na ekranie. Wysokość lub pochodzenie. Ponieważ nasza etykieta odnosi się do żółtego widoku i prefiksu oraz ich ramek jest dobrze zdefiniowany autolayout jest w stanie obliczyć ramkę naszej etykiety.

Krok 5: Teraz, gdy przypomnimy sobie, uświadomimy sobie, że daliśmy stały widok na żółty widok, ale chcemy, aby był dynamiczny w zależności od tekstu naszej etykiety, więc zmodyfikujemy nasze ograniczenie szerokości żółtego widoku. Szerokość żółtego widoku jest konieczne, aby rozwiązać niejednoznaczność, ale chcemy, aby została ona unieważniona w czasie wykonywania na podstawie zawartości UILabel. Tak więc wybierzemy nasz żółty widok i przejdziemy do Inspektora rozmiarów i zredukujemy priorytet ograniczenia szerokości do 1, aby został on przekroczony. Postępuj zgodnie z obrazem podanym poniżej.

wprowadź opis zdjęcia tutaj

Krok 6: Chcemy, aby UILabel rozwijał się zgodnie z tekstem i przesuwał nasz żółty widok, więc zmniejszyliśmy priorytet żółtej szerokości widoku, teraz zwiększymy priorytet odporności na kompresję tekstu w naszym UILabel. więc zwiększymy priorytet przytulania treści UILabel. Postępuj zgodnie z obrazkiem poniżej

wprowadź opis zdjęcia tutaj

Jak widać, zwiększyliśmy priorytet przytulania treści do 500 i priorytet odporności na kompresję do 751, co z powodzeniem przeważy nad priorytetem ograniczenia szerokości 1.

Teraz buduj i uruchamiaj, zobaczysz coś w następujący sposób.

wprowadź opis zdjęcia tutaj

Jak animować za pomocą Auto Layout

Bez automatycznego układu animacja jest realizowana, zmieniając ramkę widoku w czasie. W przypadku automatycznego układu wiązania ograniczają ramkę widoku, więc zamiast tego należy animować wiązania. Ta pośrednia utrudnia wizualizację animacji.

Oto sposoby animacji za pomocą Auto-układu:

  1. Zmień stałą ograniczenia po utworzeniu za pomocą wywołań okresowych ( CADisplayLink , dispatch_source_t , dispatch_after , NSTimer ). Następnie wywołaj layoutIfNeeded aby zaktualizować ograniczenie. Przykład:

Cel C:

self.someConstraint.constant = 10.0;
[UIView animateWithDuration:0.25 animations:^{
    [self.view layoutIfNeeded];
}];

Szybki:

self.someConstraint.constant = 10.0
UIView.animate(withDuration: 0.25, animations: self.view.layoutIfNeeded)
  1. Zmień ograniczenia i wywołaj [view layoutIfNeeded] wewnątrz bloku animacji. To interpoluje między dwiema pozycjami ignorując ograniczenia podczas animacji.
[UIView animateWithDuration:0.5 animations:^{
    [view layoutIfNeeded];
}]
  1. Zmień priorytet ograniczeń . Jest to mniej obciążające procesor niż dodawanie i usuwanie ograniczeń.

  2. Usuń wszystkie ograniczenia i użyj masek automatycznych . Później musisz ustawić view.translatesAutoresizingMaskIntoConstraints = YES .

  3. Użyj wiązań, które nie kolidują z zamierzoną animacją .

  4. Użyj widoku kontenera . Ustaw nadzór za pomocą ograniczeń. Następnie dodaj widok podrzędny z ograniczeniami, które nie walczą z animacją, np .: środek względem podglądu. To zwalnia część ograniczeń dla superview, więc nie walczą z animacją w subview.

  5. Animuj warstwy zamiast widoków . Transformacje warstw nie wyzwalają automatycznego układu.

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. Zastąp układWidoki . Wywołaj [super layoutSubviews] i [super layoutSubviews] ograniczenia.

  2. Zmień ramkę w viewDidLayoutSubviews . Automatyczny układ jest stosowany w layoutSubviews , więc po layoutSubviews zmień go w viewDidLayoutSubviews .

  3. Zrezygnuj z automatycznego układu i ustaw widoki ręcznie. Możesz to zrobić nadpisując layoutSubviews / layout bez wywoływania implementacji layoutSubviews .

Szybka wskazówka: jeśli rodzic animowanego widoku nie jest interpolowany (tzn. Animacja przeskakuje od stanu początkowego do końcowego), wywołaj layoutIfNeeded() w najgłębszym widoku, który jest rodzicem animowanego widoku (innymi słowy , na które animacja nie ma wpływu). Nie wiem dokładnie, dlaczego to działa.

Rozwiąż konflikt priorytetowy UILabel

Problem : Gdy używasz wielu etykiet w widoku, może pojawić się ostrzeżenie :

wprowadź opis zdjęcia tutaj

Jak możemy naprawić to ostrzeżenie ?

Rozwiązanie : Obliczamy i ustalamy priorytety w kolejności. Priorytety muszą różnić się od etykiet. Oznacza to, że to, co ważne, otrzyma wyższy priorytet. Na przykład w moim przypadku ustawiam pionowe priorytety dla moich etykiet:

Ustawiam najwyższy priorytet dla 1. etykiety i najniższy dla 4. etykiety.

wprowadź opis zdjęcia tutaj

wprowadź opis zdjęcia tutaj

Wydaje mi się, że w ViewController efekt tych priorytetów jest trudny. Jednak jest to bardzo wyraźnie w przypadku oszacowania wysokości komórki przez UITableViewCell +.

Mam nadzieję, że to pomoże.

Rozmiar UILabel i Parentview według tekstu w UILabel

Przewodnik krok po kroku: -

Krok 1: - Ustaw ograniczenie UIView

  1. Prowadzący. 2) Góra. 3) Końcowe. (Z głównego widoku)

wprowadź opis zdjęcia tutaj

Krok 2: - Ustaw ograniczenie na etykietę 1

  1. Prowadzący 2) Top 3) Trailing (z jego superview)

wprowadź opis zdjęcia tutaj

Krok 3: - Ustaw ograniczenie na etykietę 2

  1. Prowadzący 2) Top 3) Trailing (z jego superview)

wprowadź opis zdjęcia tutaj

Krok 4: - Najtrudniejsze dać dno UILabel z UIView.

wprowadź opis zdjęcia tutaj

Krok 5: - (Opcjonalnie) Ustaw ograniczenie na UIButton

  1. Prowadzący 2) Dół 3) Spływ 4) Stała wysokość (z widoku głównego)

wprowadź opis zdjęcia tutaj

Wynik :-

wprowadź opis zdjęcia tutaj

Uwaga: - Upewnij się, że ustawiłeś Liczba linii = 0 we właściwości Label.

wprowadź opis zdjęcia tutaj

Mam nadzieję, że te informacje są wystarczające, aby zrozumieć Uoresview Autoresize według wysokości UILabel i UILabel Autoresize według tekstu.

Visual Format Language Basics: Ograniczenia w kodzie!

HVFL jest językiem zaprojektowanym w celu ograniczenia elementów interfejsu użytkownika w prosty i szybki sposób. Ogólnie rzecz biorąc, VFL ma przewagę nad tradycyjnym dostosowaniem interfejsu użytkownika w Konstruktorze interfejsów, ponieważ jest znacznie bardziej czytelny, dostępny i kompaktowy.

Oto przykład VFL, w którym trzy UIView są ograniczone od lewej do prawej, wypełniając superView.width pomocą aGradeView

"H:|[bgView][aGradeView(40)][bGradeView(40)]|"

Istnieją dwie osie, w których możemy ograniczyć obiekty interfejsu użytkownika, poziomo i pionowo.

Każda linia VFL zawsze zaczyna się od H: lub V: Jeśli żadne nie jest obecne, domyślną opcją jest H:

Idąc dalej, mamy rurociąg. | Ten symbol lub rura odnosi się do podglądu. Jeśli przyjrzysz się bliżej fragmentowi kodu VFL powyżej, zauważysz dwa z tych potoków.

Oznacza to dwa poziome końce superwizji, zewnętrzną lewą i zewnętrzną granicę.

Następnie zobaczysz nawiasy kwadratowe, w pierwszym zestawie nawiasów kwadratowych mamy bgView . Kiedy mamy nawiasy kwadratowe, odnosi się to do elementu interfejsu użytkownika, teraz możesz się zastanawiać, w jaki sposób ustanawiamy połączenie między nazwą a rzeczywistym elementem interfejsu, być może gniazdkiem?

Omówię to na końcu postu.

Jeśli spojrzysz na drugą parę nawiasów kwadratowych [aGradeView(50)] , mamy również w sobie nawiasy zamknięte, a kiedy to jest obecne, określa szerokość / wysokość w zależności od osi, która w tym przypadku wynosi 50 szerokość w pikselach.

Pierwsze nawiasy kwadratowe [bgView] nie miały wyraźnie zdefiniowanej szerokości, co oznacza, że będzie się rozciągać tak daleko, jak to możliwe.

Dobra, to wszystko na temat podstaw, więcej na temat zaawansowanych rzeczy w innym przykładzie.


na przykład:
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];

Mieszane użycie Auto-układu z nieautomatycznym układem

Czasami możesz chcieć wykonać dodatkowe czynności w obliczeniach automatycznego układu wykonanych przez sam UIKit .

Przykład: jeśli masz UIView z maskLayer , może być konieczne zaktualizowanie maskLayer gdy tylko Automatyczny układ zmieni frame UIView

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

lub jeśli chcesz podjąć dodatkowe działania w Auto Layout w ViewController

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];
    // now you can assume all your subviews are positioned/resized correctly
    self.customView.frame = self.containerView.frame;
}

Układ proporcjonalny

Ograniczenie utworzone jako

NSLayoutConstraint(item: myView, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: view, attribute: NSLayoutAttribute.LeadingMargin, multiplier: 1.0, constant: 20.0)

lub z matematycznego punktu widzenia:

view.attribute * multiplier + constant          (1)

Za pomocą mnożnika można utworzyć układ proporcjonalny dla różnych współczynników wielkości.

Przykład:

Widok turkusowy (V1) jest kwadratem o proporcjonalnej szerokości w widoku proporcjonalnym o stosunku 1: 1,1

Gary Square (V2) to podview V1. Dolna przestrzeń ustawiona przez stałą = 60, Końcowa przestrzeń ustawiona przez mnożnik = 1,125 i stała = 0

Końcowe odstępy ustawione proporcjonalnie, dolne odstępy ustawione jako stałe.

wprowadź opis zdjęcia tutaj

Uwaga: jeśli view.attribute jest równe 0 (na przykład spacja wiodąca), formuła ograniczenia (1) będzie równa 0. Musisz zmienić drugi element ograniczenia lub ustawić ograniczenie względem marginesu, aby view.attribute! = 0.

NSLayoutConstraint: Ograniczenia w kodzie!

Gdy pracujemy nad strukturą, jeśli ograniczenia nie są zbyt skomplikowane, lepiej użyć Konstruktora interfejsów lub NSLayoutConstraint w kodzie, aby był wystarczająco mały, zamiast importować Masonry lub SnapKit.

na przykład:
wprowadź opis zdjęcia tutaj

  • Cel 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
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow