autolayout - ustaw wysokość widoku względem połowy wysokości nadzoru

136

dostaję się ostatnio do autoukładów i utknąłem na tym, co wydaje się naprawdę trywialnym przykładem problemu. Mam widok, który chcę usiąść u góry ekranu i zajmować połowę jego wysokości. Proste przed automatycznym układem - po prostu przymocuj go na miejscu i powiedz, aby rozszerzał się w pionie, gdy zmienia się rozmiar superview.

Teraz nie mogę za całe życie zobaczyć, jak to zrobić. Oto, co otrzymuję, gdy próbuję to skonfigurować:

autolayout blues

Ograniczenie dolnej przestrzeni jest ustawione na „równa się 284”, co jest dla mnie absolutne i absolutnie bezużyteczne, gdy zmieniam układ na iPhone4, ponieważ zachowuje 284 punkty miejsca na dole ekranu i zmniejsza widok, aby nie był już połową rozmiar ekranu. I nie ma sposobu, aby to ograniczenie było równe jakiejś części wysokości dowolnego innego widoku.

Po chwili zmagania się, jedynym sposobem, w jaki mogę o tym pomyśleć, byłoby wprowadzenie innego widoku poniżej tego widoku, równe przypięcie ich wysokości, umieszczenie ich nad i pod sobą, a następnie ustawienie drugiego (dolnego) widoku jako niewidocznego .. co wydaje się trochę brzydkie!

Czy brakuje mi czegoś oczywistego?

Zmierzyć
źródło
1
Nie sądzę, żeby to było brzydkie, ale sprytna sztuczka, aby uzyskać to, czego chcesz za pomocą IB. Zrobiłem to i używając odpowiednich nazw elementów, możesz jasno określić, co się dzieje. Możesz nawet mieć trzeci element w innej pozycji lub środkach, zmienić rozmiar na podstawie tych dwóch podwidoków.
Jelle,

Odpowiedzi:

167

Jest to teraz możliwe w IB od [przynajmniej] Xcode 5.1.1. Chociaż zajęło mi trochę czasu, zanim zrozumiałem, jest to w rzeczywistości bardzo proste:

Najpierw utwórz podstawowe ograniczenie wyrównania do góry (musisz również ustawić ograniczenia do dołu, do lewej i do prawej, jak zwykle). Następnie wybierz ograniczenie i przejdź do Inspektora atrybutów :

Demonstracja powyższych kroków

Następnie możesz dostosować mnożnik. Jeśli chcesz, aby to 50% super widoku, pozostaw je na 1, ponieważ jest wyrównane do środka super-widoku . Jest to również świetny sposób na tworzenie wyświetleń, które również stanowią inne wartości procentowe (np. 25% super wyświetleń)

Demonstracja drugiego kroku powyżej

Firo
źródło
fajnie :) Myślę, że ten post powinien być oznaczony jako zaakceptowana odpowiedź :) Programista iOS często preferuje rozwiązanie Interface Builder zamiast rozwiązania w postaci kodu
hqt
@hqt, dzięki. Myślę, że kiedy została napisana zaakceptowana odpowiedź, ta metoda nie była dostępna. Czasami pytający nie powracają do starych pytań lub nie chcą zmienić zaakceptowanej odpowiedzi. Ale ostatecznie jestem tutaj, aby pomóc, cieszę się, że tak się stało!
Firo
3
Jestem nieco zdezorientowany. Próbowałem tego, ale po prostu wyśrodkowuje widok do podglądu, nie dostosowuje wysokości widoku.
Dean
@Dean, musisz się upewnić, że nie First Itemjest . W przeciwnym razie tak, po prostu wyśrodkuje. Będziesz także musiał upewnić się, że inne wiązania są ustawione prawidłowo, aby obsługiwać inne krawędzie widoku. View.TopView.Center Y
Firo
1
View.Top równa się Superview.Center Y mnożnik 1 nie daje żadnej wysokości. Ta odpowiedź jest niepełna. Wszystko, co musisz zrobić, to pomyśleć o tym, co mówisz, a zobaczysz, że wyświetla się linia przez środek! Zmieniłbym tę odpowiedź, aby było jasne, o jakich innych ograniczeniach mówisz.
smileBot
184

Rozwiązanie scenorysowe, w którym możesz ustawić dokładny stosunek między dowolnymi widokami:

Ustaw ograniczenie równości wysokości

Teraz:

Edytuj mnożnik ograniczenia

ZYSK!!!

Wynik

PS Należy również zauważyć, że ta metoda działa z widokami na różnych poziomach zagnieżdżenia i (oczywiście) ma zastosowanie do szerokości

PPS czasami może być pomocne „odwrócenie pierwszej i drugiej pozycji” ograniczenia lub ustawienie odwrotnego mnożnika (na przykład 2 zamiast 0,5) (ale te metody nie są pomocne, jeśli nie rozumiesz, w jaki sposób widoki odnoszą się do siebie).

Fyodor Volchyok
źródło
1
Krok 2 wydaje się nie działać dla mnie. Nie mogę wybrać niczego w panelu poza przełączaniem „Ograniczenie do marginesu”. Próbuję ustawić szerokość UIImageView w UITableViewCell na 50% widoku zawartości.
DrMickeyLauer
2
AKTUALIZACJA: Oczywiście konstruktor interfejsu nie pozwala, aby widok zawartości był jawnym celem jakichkolwiek ograniczeń układu automatycznego. Aby to zadziałało, muszę wstawić fałszywy widok podrzędny jako element podrzędny widoku treści.
DrMickeyLauer
1
Mi to pasuje. Musisz wybrać dwa widoki na liście, a nie ekran konstruktora. dla procentów podziel mniejszy widok przez większy widok, aby uzyskać wartość mnożnika. przykład mniejszy widok 25, większy widok 135-25 / 135 = 0,185. Ustaw to jako wartość mnożnika, aby uzyskać widok, który przy x1 i x2 = 25, ale skaluje się wraz z większymi 6 i 6 plus itd.
latenitecoder
1
To zadziałało dla mnie, ale pamiętaj, że musiałem również dodać trzy ograniczenia, które ustawiają ograniczenia marginesu
podglądy
To powinna być akceptowana odpowiedź. Najpierw próbuję zaakceptować odpowiedź. Nie zadziałało, potem przewinęłam w dół i zobaczyłam tę odpowiedź i zadziałało. Dzięki!
Mihir Oza
31

Po pewnym czasie doszedłem do następujących rzeczy.

Odnotowuję to jako odpowiedź, ale nie jest to zbyt satysfakcjonujące, ponieważ zakłada, że ​​nie możesz tego zrobić w Interface Builder, ale poprawne ograniczenie można później dodać w kodzie jako:

- (void) viewWillAppear:(BOOL)animated
{

    NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:upperview
                                                                 attribute:NSLayoutAttributeHeight 
                                                                 relatedBy:0 
                                                                    toItem:self.view
                                                                 attribute:NSLayoutAttributeHeight
                                                                multiplier:.5 
                                                                  constant:0];
    [self.view addConstraint:constraint];

}

Zasadniczo ustawia mnożnik 0,5 względem wysokości widzenia siebie, działając na widok górny. Musiałem ustawić priorytet dolnego ograniczenia przestrzeni pionowej w IB na mniej niż 1000, aby uniknąć wielu komunikatów w czasie wykonywania również o łamaniu ograniczeń.

Więc jeśli ktoś może pokazać, jak to zrobić w Interface Builder, to lepiej odpowiedziałoby na moje pytanie, w przeciwnym razie myślę, że to jest tak dobre, jak to tylko możliwe (na razie) ???

Zmierzyć
źródło
3
Myślę, że to jest tak dobre, jak teraz. Byłoby miło, gdyby Apple dał nam dostęp do wartości mnożnika w IB, aby można było ustawić tak samo, jak stałą.
rdelmar
3
Dla każdego, kto patrzy na tę odpowiedź, Xcode 5.1 pozwala teraz ustawić mnożnik za pomocą Interface Builder. Jestem teraz w stanie skonfigurować widoki, które są o połowę mniejsze od ich superviewów, wszystko za pośrednictwem IB.
Mark Krenek,
9

Nieco łatwiejsze i prostsze niż metoda niż odpowiedź Fiodora Volchyoka. -Przytrzymaj przycisk sterowania i kliknij widok podrzędny. -Nadal przytrzymując przycisk polecenia, przeciągnij kursor do widoku nadzoru, a następnie kliknij widok nadzoru. -Wybierz „Aspect Ratio”.

wprowadź opis obrazu tutaj

-Następnie kliknij Inspektor rozmiaru. -Następnie kliknij dwukrotnie ograniczenie. wprowadź opis obrazu tutaj

-Upewnij się, że dla obu pozycji wybrano „wysokość”. wprowadź opis obrazu tutaj

-Następnie zmień „Mnożnik” na 0,5 dla połowy ekranu lub dowolnej części superwizji, którą chcesz. wprowadź opis obrazu tutaj

user444333222
źródło
Łatwe i szybkie podejście! Dzięki kolego
Abdullah Saeed
7

Istnieje również inna możliwość w kodzie w przypadku, gdy masz 2 widoki, które powinny mieć tę samą wysokość: po prostu ustaw wysokość view2 na wysokość view1 (sztuczka tutaj nie polega na jawnym ustawianiu wysokości view1).

    [self.view addConstraints:[NSLayoutConstraint
        constraintsWithVisualFormat:@"V:[topLayoutGuide]-0-[_view1]-0-[_view2(==_view1)]-0-[bottomLayoutGuide]"
                            options:0
                            metrics:nil
                              views:viewsDict]];
Mózg
źródło
Nie zdawałem sobie sprawy, że możesz odnosić się do innych widoków dla takich szerokości / wysokości. To najczystsza odpowiedź IMO, jeśli jesteś już w języku formatu wizualnego.
loeschg,
Przykład @brainray jest również wyjaśniony na developer.apple.com tutaj
alecs.popa
0

Szybka wersja odpowiedzi Mete:

    override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.



    upperView.translatesAutoresizingMaskIntoConstraints = false


    var constraint = NSLayoutConstraint(item: upperView,
                                        attribute: NSLayoutAttribute.top,
                                        relatedBy: NSLayoutRelation.equal,
                                        toItem: self.view,
                                        attribute: NSLayoutAttribute.top,
                                        multiplier: 1,
                                        constant: 0)

    self.view.addConstraint(constraint)


    constraint = NSLayoutConstraint(item: upperView,
                                    attribute: NSLayoutAttribute.height,
                                    relatedBy: NSLayoutRelation.equal,
                                    toItem: self.view,
                                    attribute: NSLayoutAttribute.height,
                                    multiplier: 0.5,
                                    constant: 0)

    self.view.addConstraint(constraint)


    constraint = NSLayoutConstraint(item: upperView,
                                    attribute: NSLayoutAttribute.leading,
                                    relatedBy: NSLayoutRelation.equal,
                                    toItem: self.view,
                                    attribute: NSLayoutAttribute.leading,
                                    multiplier: 1,
                                    constant: 0)

    self.view.addConstraint(constraint)


    constraint = NSLayoutConstraint(item: upperView,
                                    attribute: NSLayoutAttribute.trailing,
                                    relatedBy: NSLayoutRelation.equal,
                                    toItem: self.view,
                                    attribute: NSLayoutAttribute.trailing,
                                    multiplier: 1,
                                    constant: 0)

    self.view.addConstraint(constraint)


}
user444333222
źródło