Załóżmy, że dodałem więcej widoków w UIStackView, które można wyświetlić, jak mogę zrobić UIStackView
przewijanie?
ios
uiscrollview
uistackview
swój kod
źródło
źródło
Odpowiedzi:
W przypadku, gdy ktoś szuka rozwiązania bez kodu , stworzyłem przykład, aby zrobić to całkowicie w serii ujęć, używając Auto Layout.
Możesz go zdobyć z github .
Zasadniczo, aby odtworzyć przykład (do przewijania w pionie):
UIScrollView
i ustaw jego ograniczenia.UIStackView
doUIScrollView
Leading
,Trailing
,Top
iBottom
powinny być równe tym, jakie odUIScrollView
Width
ograniczenie międzyUIStackView
iUIScrollView
.UIStackView
UIViews
doUIStackView
Wymiana
Width
naHeight
w kroku 4, a zestawAxis
=Horizontal
w kroku 5, aby uzyskać poziomą UIStackView.źródło
Przewodnik automatycznego układu Apple zawiera całą sekcję dotyczącą pracy z widokami przewijania . Niektóre istotne fragmenty:
Ponadto:
Podsumowując, widok zawartości widoku przewijania (w tym przypadku widok stosu) musi być przypięty do jego krawędzi i mieć ograniczoną szerokość i / lub wysokość. Oznacza to, że zawartość widoku stosu musi być ograniczona (bezpośrednio lub pośrednio) w kierunku (kierunkach), w którym pożądane jest przewijanie, co może na przykład oznaczać dodanie ograniczenia wysokości do każdego widoku wewnątrz widoku stosu przewijanego pionowo. Oto przykład, w jaki sposób zezwolić na pionowe przewijanie widoku przewijania zawierającego widok stosu:
źródło
Need constraints for: Y position or height.
Ten błąd znika tylko wtedy, gdy ustawisz ograniczenie szerokości i wysokości dla widoku stosu, co wyłącza przewijanie w pionie. Czy ten kod nadal działa dla Ciebie?Ograniczenia w najczęściej głosowanej odpowiedzi tutaj działały dla mnie i wkleiłem obraz ograniczeń poniżej, utworzony w moim scenariuszu.
Dotknąłem dwóch kwestii, o których inni powinni wiedzieć:
Po dodaniu ograniczeń podobnych do tych w zaakceptowanej odpowiedzi otrzymałem czerwony błąd autolayout
Need constraints for: X position or width
. Zostało to rozwiązane przez dodanie UILabel jako widoku podrzędnego widoku stosu.Dodam podview programowo, więc pierwotnie nie miałem podviewów w serii ujęć. Aby pozbyć się błędów autoukładu, dodaj widok podrzędny do scenorysu, a następnie usuń go podczas ładowania przed dodaniem prawdziwych widoków podrzędnych i ograniczeń.
Początkowo próbowałem dodać
UIButtons
do UIStackView. Przyciski i widoki zostaną załadowane, ale widok przewijania nie przewinie się . Zostało to rozwiązane poprzez dodanieUILabels
do widoku stosu zamiast przycisków. Korzystając z tych samych ograniczeń, ta hierarchia widoku ze zwojami UILabels przewija się, ale UIButtons nie.Jestem zdezorientowany tym problemem, ponieważ UIButtons nie wydają się mieć IntrinsicContentSize (używany przez widok stosu). Jeśli ktoś wie, dlaczego przyciski nie działają, chciałbym wiedzieć, dlaczego.
Oto moja hierarchia widoku i ograniczenia w celach informacyjnych:
źródło
Jak mówi Eik
UIStackView
iUIScrollView
bawcie się dobrze, patrz tutaj .Kluczem jest to, że
UIStackView
obsługuje zmienną wysokość / szerokość dla różnych treści, aUIScrollView
następnie dobrze wykonuje przewijanie / odbijanie tej zawartości:źródło
Chciałem zrobić to samo i natknąłem się na ten znakomity post. Jeśli chcesz to zrobić programowo przy użyciu interfejsu API kotwicy, jest to odpowiedni sposób.
Podsumowując, umieść swoją
UIStackView
w swoimUIScrollView
i ustaw ograniczenia kotwicy,UIStackView
aby pasowały doUIScrollView
:źródło
Do 2020 roku.
100% scenorysu LUB 100% kodu.
Oto najprostsze możliwe wyjaśnienie:
Miej pustą scenę pełnoekranową
Dodaj widok przewijania. Przeciągnij z wciśniętym klawiszem Control z widoku przewijania do widoku podstawowego , dodaj lewy-prawy-górny-dolny, wszystkie zero.
Dodaj widok stosu w widoku przewijania. Przeciągnij z wciśniętym klawiszem Control z widoku stosu do widoku przewijania , dodaj lewy-prawy-górny-dolny, wszystkie zero.
Umieść dwie lub trzy etykiety w widoku stosu.
Dla jasności zmień kolor tła etykiety na czerwony. Ustaw wysokość etykiety na 100.
Teraz ustaw szerokość każdego UILabel:
Nieoczekiwanie przeciągnij z wciśniętym klawiszem Control
UILabel
do widoku przewijania, a nie do stosu i wybierz równe szerokości .Powtarzać:
Nie kontroluj przeciągania z UILabel do rodzica UILabel - idź do dziadka. (Innymi słowy, przejdź do widoku przewijania, nie przechodź do widoku stosu).
To takie proste. To jest sekret.
Jesteś skończony.
Wskazówka: musisz dodać wysokość do każdego nowego elementu . Każdy element w dowolnym przewijanym widoku stosu musi mieć rzeczywisty rozmiar (na przykład etykietę) lub musi zawierać wyraźne ograniczenie wysokości.
Alternatywne podejście:
Powyżej: nieoczekiwanie, ustaw szerokość UILabels na szerokość widoku przewijania (nie widoku stosu).
Na przemian...
Przeciągnij z widoku stosu do widoku przewijania i dodaj ograniczenie „równej szerokości”. To wydaje się dziwne, ponieważ już przypiąłeś lewy-prawy , ale w ten sposób to robisz . Bez względu na to, jak dziwne to się wydaje, to jest sekret.
Masz więc dwie opcje:
lub
Żeby było jasne, wykonaj JEDNĄ z tych metod, NIE rób obu.
źródło
Przewijanie w poziomie (UIStackView w UIScrollView)
Do przewijania w poziomie. Najpierw utwórz a
UIStackView
i aUIScrollView
i dodaj je do swojego widoku w następujący sposób:Pamiętaj, aby ustawić
translatesAutoresizingMaskIntoConstraints
opcjęfalse
naUIStackView
iUIScrollView
:Aby wszystko działało, kotwice końcowe, wiodące, górne i dolne
UIStackView
powinny być równeUIScrollView
kotwicom:Ale szerokość kotwicy
UIStackView
moszczu jest równa lub większa niż szerokośćUIScrollView
kotwicy:Teraz zakotwicz swoje
UIScrollView
, na przykład:Następnie sugeruję wypróbowanie następujących ustawień
UIStackView
wyrównywania i dystrybucji:Na koniec musisz użyć tej
addArrangedSubview:
metody, aby dodać widoki podrzędne do swojego UIStackView.Wstawki tekstowe
Jedną dodatkową funkcją, która może okazać się przydatna, jest to, że ponieważ
UIStackView
jest ona trzymana w środku,UIScrollView
masz teraz dostęp do wstawek tekstowych, aby wyglądać nieco ładniej.źródło
Po prostu dodaj to do
viewdidload
:źródło: https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/LayoutUsingStackViews.html
źródło
Możesz wypróbować ScrollableStackView : https://github.com/gurhub/ScrollableStackView
Jest to biblioteka zgodna z Objective-C i Swift. Jest dostępny za pośrednictwem CocoaPods .
Przykładowy kod (Swift)
Przykładowy kod (Objective-C)
źródło
Jeśli masz ograniczenie do wyśrodkowania widoku stosu pionowo w widoku przewijania, po prostu go usuń.
źródło
Przykład pionowego widoku stosu / widoku przewijania (przy użyciu opcji
EasyPeasy
autolayout):Upewnij się tylko, że wysokość każdego widoku jest zdefiniowana!
źródło
Przede wszystkim zaprojektuj swój widok, najlepiej w coś takiego jak Szkic lub dowiedz się, czego chcesz jako przewijanej zawartości.
Następnie ustaw dowolny kontroler widoku (wybierz z Inspektora atrybutów) i ustaw wysokość i szerokość zgodnie z wewnętrznym rozmiarem zawartości twojego widoku (do wyboru z Inspektora rozmiarów).
Po tym w kontrolerze widoku umieść widok przewijania i jest to logika, która, jak się okazało, działa prawie cały czas w iOS (może wymagać przejrzenia dokumentacji tej klasy widoku, którą można uzyskać za pomocą polecenia + kliknięcie na ta klasa lub przez googling)
Jeśli pracujesz z dwoma lub więcej widokami, najpierw zacznij od widoku, który został wprowadzony wcześniej lub jest bardziej prymitywny, a następnie przejdź do widoku, który został wprowadzony później lub jest bardziej nowoczesny. Więc tutaj, ponieważ najpierw wprowadzono widok przewijania, zacznij od widoku przewijania, a następnie przejdź do widoku stosu. Tutaj ustaw zerowane ograniczenia widoku przewijania we wszystkich kierunkach względem jego super widoku. Umieść wszystkie swoje widoki w tym widoku przewijania, a następnie umieść je w widoku stosu.
Podczas pracy z widokiem stosu
Najpierw zacznij od podstaw (podejście do dołu), tj. Jeśli masz w widoku etykiety, pola tekstowe i obrazy, a następnie najpierw ułóż te widoki (wewnątrz widoku przewijania), a następnie umieść je w widoku stosu.
Następnie dostosuj właściwość widoku stosu. Jeśli pożądany widok nadal nie został osiągnięty, użyj innego widoku stosu.
Po utworzeniu widoku umieść ograniczenie między widokiem stosu macierzystego a widokiem przewijania, a widok stosu potomnego z wiązaniem z widokiem stosu macierzystego. Mam nadzieję, że do tego czasu powinno działać dobrze lub możesz otrzymać ostrzeżenie od Xcode podające sugestie, przeczytaj to, co mówi i zaimplementuj je. Mam nadzieję, że teraz powinieneś mieć widok roboczy zgodny ze swoimi oczekiwaniami :).
źródło
W przypadku zagnieżdżonego lub pojedynczego widoku stosu należy przewijać widok przewijania w widoku głównym. Widok głównego stosu wewnątrz widoku przewijania musi mieć tę samą szerokość. [Mój widok przewijania jest poniżej widoku, zignoruj go]
źródło
Jeśli ktoś szuka widoku przewijanego w poziomie
źródło
Umieść przewijany widok na scenie i zmień go tak, aby wypełnił scenę. Następnie umieść widok stosu w widoku przewijania i umieść przycisk dodawania elementu w widoku stosu. Jak tylko wszystko będzie na swoim miejscu, ustaw następujące ograniczenia:
kod:
Stack View.Width = Scroll View.Width
jest kluczem.źródło
Dodanie nowej perspektywy dla macOS Catalyst. Ponieważ aplikacje macOS obsługują zmianę rozmiaru okna, możliwe jest, że
UIStackView
zmienisz stan z niekodowalnego na przewijalny lub odwrotnie. Są tu dwie subtelne rzeczy:UIStackView
jest zaprojektowany tak, aby pasował do wszystkich obszarów, w których może.UIScrollView
spróbuje zmienić rozmiar swoich granic, aby uwzględnić nowo uzyskany / utracony obszar pod paskiem nawigacji (lub paskiem narzędzi w przypadku aplikacji macOS).To niestety stworzy nieskończoną pętlę. Nie jestem zbytnio zaznajomiony z tym
UIScrollView
i jegoadjustedContentInset
, ale z logu w jegolayoutSubviews
metodzie widzę następujące zachowanie:UIScrollView
próbuje zmniejszyć swoje granice (ponieważ nie ma potrzeby obszaru pod paskiem narzędzi).UIStackView
następuje.UIScrollView
jest niezadowolony i postanawia przywrócić do większych granic. To wydaje mi się bardzo dziwne, ponieważ to, co widzę w dzienniku, jest takieUIScrollView.bounds.height == UIStackView.bounds.height
.UIStackView
następuje.Wydaje mi się, że dwa kroki rozwiązałyby ten problem:
UIStackView.top
doUIScrollView.topMargin
.contentInsetAdjustmentBehavior
na.never
.Mam tu na myśli przewijany pionowo widok z rosnącym pionowo
UIStackView
. W przypadku pary poziomej odpowiednio zmień kod.Mam nadzieję, że pomoże każdemu w przyszłości. Nie mogłem znaleźć nikogo, kto wspominałby o tym w Internecie, a ustalenie, co się stało, kosztowało mnie sporo czasu.
źródło