iOS
Układ automatyczny
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żetrailingAnchor
,topAnchor
ibottomAnchor
.
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:
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.
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.
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”.
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.
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:
Po wydaniu pojawi się menu opcji ograniczeń:
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
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.
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
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.
Po dodaniu tych dwóch ograniczeń zobaczysz, że XCode daje ci błędy, jak na poniższym obrazku pozwala je zobaczyć i zrozumieć.
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
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.
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
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.
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
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.
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:
- Zmień stałą ograniczenia po utworzeniu za pomocą wywołań okresowych (
CADisplayLink
,dispatch_source_t
,dispatch_after
,NSTimer
). Następnie wywołajlayoutIfNeeded
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)
- 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];
}]
Zmień priorytet ograniczeń . Jest to mniej obciążające procesor niż dodawanie i usuwanie ograniczeń.
Usuń wszystkie ograniczenia i użyj masek automatycznych . Później musisz ustawić
view.translatesAutoresizingMaskIntoConstraints = YES
.Użyj wiązań, które nie kolidują z zamierzoną animacją .
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.
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];
Zastąp układWidoki . Wywołaj
[super layoutSubviews]
i[super layoutSubviews]
ograniczenia.Zmień ramkę w viewDidLayoutSubviews . Automatyczny układ jest stosowany w
layoutSubviews
, więc polayoutSubviews
zmień go wviewDidLayoutSubviews
.Zrezygnuj z automatycznego układu i ustaw widoki ręcznie. Możesz to zrobić nadpisując
layoutSubviews
/layout
bez wywoływania implementacjilayoutSubviews
.
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 :
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.
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
- Prowadzący. 2) Góra. 3) Końcowe. (Z głównego widoku)
Krok 2: - Ustaw ograniczenie na etykietę 1
- Prowadzący 2) Top 3) Trailing (z jego superview)
Krok 3: - Ustaw ograniczenie na etykietę 2
- Prowadzący 2) Top 3) Trailing (z jego superview)
Krok 4: - Najtrudniejsze dać dno UILabel z UIView.
Krok 5: - (Opcjonalnie) Ustaw ograniczenie na UIButton
- Prowadzący 2) Dół 3) Spływ 4) Stała wysokość (z widoku głównego)
Wynik :-
Uwaga: - Upewnij się, że ustawiłeś Liczba linii = 0 we właściwości Label.
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.
// 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.
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.
- 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];