Czy można przewijać UIStackView?

Powiedzmy, że dodałem więcej widoków w UIStackView, które mogą być wyświetlane, Jak mogę zrobić UIStackView przewijanie?

Author: Honey, 2015-07-28

13 answers

Na wypadek, gdyby ktoś szukał rozwiązania bez kodu , stworzyłem przykład, aby zrobić to całkowicie w storyboardzie, używając automatycznego układu.

Możesz go pobrać z github .

Zasadniczo, aby odtworzyć przykład:

  1. Utwórz UIScrollView i ustaw jego ograniczenia.
  2. dodaj UIStackView do UIScrollView
  3. Ustaw ograniczenia: Leading, Trailing, Top & Bottom powinny być równe tym z UIScrollView
  4. ustaw równe Width ograniczenie pomiędzy UIStackView i UIScrollView.
  5. Set Axis= Vertical, Alignment = Fill, Distribution = Equal Spacing, and Spacing = 0 Na UIStackView
  6. dodaj liczbę UIViews do UIStackView
  7. Run
 376
Author: Arjan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-01 17:06:07

Podręcznik Auto Layout firmy Apple zawiera całą sekcję dotyczącą pracy z widokami przewijania . Niektóre istotne fragmenty:

  1. Przypnij górną, dolną, wiodącą i końcową krawędź widoku zawartości do odpowiednich krawędzi widoku przewijania. Widok zawartości definiuje teraz obszar zawartości widoku przewijania.
  2. (opcjonalne)aby wyłączyć przewijanie poziome, ustaw szerokość widoku zawartości równą szerokości widoku przewijania. Widok zawartości wypełnia teraz widok przewijania poziomo.
  3. (opcjonalne)aby wyłączyć przewijanie w pionie, Ustaw wysokość widoku zawartości równą wysokości widoku przewijania. Widok zawartości teraz wypełnia się przewijanie w poziomie.

Ponadto:

Twój układ musi w pełni określić rozmiar widoku zawartości (z wyjątkiem jeżeli określono to w krokach 5 i 6). ... Gdy Widok zawartości jest wyższy niż widok przewijania, widok przewijania umożliwia przewijanie w pionie. Gdy Widok zawartości jest szerszy niż widok przewijania, widok przewijania umożliwia przewijanie w poziomie.

Podsumowując, Widok zawartości widoku przewijania (w tym przypadku Widok stosu) musi być przypięty do jego krawędzi i musi mieć w inny sposób ograniczoną szerokość i/lub wysokość. Oznacza to, że zawartość widoku stosu musi być ograniczona (bezpośrednio lub pośrednio) w kierunku, w którym pożądane jest przewijanie, co może oznaczać dodanie ograniczenia wysokości do każdego widoku wewnątrz pionowo przewijanego widoku stosu, dla przykład. Poniżej przedstawiono przykład, jak zezwolić na przewijanie w pionie widoku przewijania zawierającego widok stosu:

// Pin the edges of the stack view to the edges of the scroll view that contains it
stackView.topAnchor.constraintEqualToAnchor(scrollView.topAnchor).active = true
stackView.leadingAnchor.constraintEqualToAnchor(scrollView.leadingAnchor).active = true
stackView.trailingAnchor.constraintEqualToAnchor(scrollView.trailingAnchor).active = true
stackView.bottomAnchor.constraintEqualToAnchor(scrollView.bottomAnchor).active = true

// Set the width of the stack view to the width of the scroll view for vertical scrolling
stackView.widthAnchor.constraintEqualToAnchor(scrollView.widthAnchor).active = true
 21
Author: titaniumdecoy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-12 17:48:28

Jak mówi Eik, UIStackView i UIScrollView grają razem ładnie, zobacz Tutaj .

Kluczem Jest to, że UIStackView obsługuje zmienną wysokość/szerokość dla różnych treści, a UIScrollView dobrze wykonuje swoje zadanie przewijania / odbijania tej zawartości:

override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        scrollView.contentSize = CGSize(width: stackView.frame.width, height: stackView.frame.height)       
}
 10
Author: user1307434,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-27 04:56:13

Chciałem zrobić to samo i natknąłem się na ten doskonały post. jeśli chcesz to zrobić programowo za pomocą anchor API, jest to droga do zrobienia.

Podsumowując, umieść swoje UIStackView w swoim UIScrollView i ustaw ograniczenia kotwicy UIStackView, aby pasowały do tych z UIScrollView:

stackView.leadingAnchor.constraintEqualToAnchor(scrollView.leadingAnchor).active = true
stackView.trailingAnchor.constraintEqualToAnchor(scrollView.trailingAnchor).active = true
stackView.bottomAnchor.constraintEqualToAnchor(scrollView.bottomAnchor).active = true
stackView.topAnchor.constraintEqualToAnchor(scrollView.topAnchor).active = true
stackView.widthAnchor.constraintEqualToAnchor(scrollView.widthAnchor).active = true
 8
Author: Dalmazio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-14 09:05:23

Ograniczenia w najczęściej głosowanej odpowiedzi zadziałały dla mnie, a ja wkleiłem obraz ograniczeń poniżej, stworzony w moim storyboardzie.

Uderzyłem w dwie kwestie, choć inni powinni być świadomi:

  1. Po dodaniu ograniczeń podobnych do tych w zaakceptowanej odpowiedzi dostałbym czerwony błąd autolayout Need constraints for: X position or width. Zostało to rozwiązane przez dodanie etykiety UILabel jako podglądu podrzędnego widoku stosu.

    Dodaję podglądy programowo, więc początkowo nie miałem podglądy na storyboardzie. Aby pozbyć się błędów autolayout, dodaj subview do storyboardu, a następnie usuń go przy ładowaniu przed dodaniem prawdziwych podwizów i ograniczeń.

  2. Początkowo próbowałem dodać UIButtons do UIStackView. Przyciski i widoki zostaną załadowane, ale widok przewijania nie będzie przewijał . Zostało to rozwiązane przez dodanie UILabels do widoku stosu zamiast przycisków. Używając tych samych ograniczeń, ta hierarchia widoku z UILabels przewija, ale UIButtons nie.

    Jestem zdezorientowany tym problemem, ponieważ Uibuttony czy wydają się mieć wewnętrzny Rozmiar (używany przez Widok stosu). Jeśli ktoś wie, dlaczego przyciski nie działają, chciałbym wiedzieć dlaczego.

Oto moja hierarchia poglądów i ograniczenia, w celach informacyjnych:

ograniczenia dla widoku stosu w widoku przewijania [1]

 6
Author: pkamb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-22 18:24:15

Wystarczy dodać to do viewdidload:

let insets = UIEdgeInsetsMake(20.0, 0.0, 0.0, 0.0)
scrollVIew.contentInset = insets
scrollVIew.scrollIndicatorInsets = insets

Źródło: https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/LayoutUsingStackViews.html

 5
Author: rashad.z,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-16 17:33:27

Możesz spróbować ScrollableStackView : https://github.com/gurhub/ScrollableStackView

Jest biblioteką zgodną z Objective-C i Swift. Jest dostępny przez CocoaPods .

Przykładowy Kod (Swift)

import ScrollableStackView

var scrollable = ScrollableStackView(frame: view.frame)
view.addSubview(scrollable)

// add your views with 
let rectangle = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 55))
rectangle.backgroundColor = UIColor.blue
scrollable.stackView.addArrangedSubview(rectangle)
// ...

Przykładowy Kod (Objective-C)

@import ScrollableStackView

ScrollableStackView *scrollable = [[ScrollableStackView alloc] initWithFrame:self.view.frame];
scrollable.stackView.distribution = UIStackViewDistributionFillProportionally;
scrollable.stackView.alignment = UIStackViewAlignmentCenter;
scrollable.stackView.axis = UILayoutConstraintAxisVertical;
[self.view addSubview:scrollable];

UIView *rectangle = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 55)];
[rectangle setBackgroundColor:[UIColor blueColor]];

// add your views with
[scrollable.stackView addArrangedSubview:rectangle]; 
// ...
 2
Author: mgyky,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-20 19:52:21

Oto najprostsze możliwe Wyjaśnienie:

  1. Miej pustą scenę pełnoekranową

  2. Dodaj widok przewijania. Control-przeciągnij z widoku przewijania do widoku bazowego , dodaj lewy-prawy-górny-dolny, wszystkie zero.

  3. Dodaj widok stosu w widoku przewijania. Control-przeciągnij z widoku stosu do widoku przewijania , dodaj lewo-prawo-góra-dół, wszystkie zero.

  4. Umieść jeden znak UILabel w widoku stosu.

Dla jasności, Ustaw kolor tła na czerwony; Ustaw wysokość na 100, a w widoku stosu Ustaw odstępy na 20.

  1. Teraz ustaw szerokość UILabel:

    Co zaskakujące, przeciągnij z {[0] } do widoku przewijania, Nie widok stosu i wybierz równe szerokości.

Do powtórzenia:

Nie kontroluj przeciągania z UILabel do rodzica UILabel - idź do dziadka. (Innymi słowy, przejdź do widoku przewijania, nie idź do stosu widok.)

To takie proste. W tym tkwi sekret.
  1. Następnie, musiszkliknąć na jeden UILabel, a musisz dosłownie wcisnąć kopiuj-wklej kilka razy. To nie będzie działać z tylko jednym elementem. (Nie klikaj "duplicate", kliknij "copy then paste".)
Jesteś skończony. To takie proste.

Wskazówka: spróbuj dodać nowy element do widoku stosu, powiedzmy UIView (być może do użycia jako spacja). Zauważ, że wszystko idzie źle. W rzeczywistości musisz dodaj wysokość do każdego nowego elementu (powiedzmy "100"). Za każdym razem, gdy dodajesz nowy element, musisz nadać mu jakąś Wysokość .


Inny sposób na to:

W powyższym, mówi to: zaskakująco, Ustaw szerokości UILabels na szerokość widoku przewijania (nie Widok stosu). To działa idealnie.

/ Align = "left" / ..

Zauważ, że widok stosu został przypięty w lewo i w prawo do swojego nadrzędnego widoku przewijania. Spróbuj tego:

Przeciągnij ze stosu widok do widoku przewijania i dodaj ograniczenie "szerokość równa". Wydaje się to dziwne, ponieważ już przypiąłeś lewo-prawo, ale tak to robisz . Nie ważne jak dziwnie się to wydaje, to jest sekret.

Więc masz dwie opcje:

  1. zaskakująco, ustaw szerokość UILabels na szerokość przewijania (Nie rodzic stackview).

Lub

  1. zaskakująco, ustaw" szerokość równą" stackview do widoku przewijania - chociaż lewa i prawa krawędź widoku stackview jest przypięta do widoku przewijania.

Żeby było jasne, zrób jedną z tych metod, nie rób obu.

 2
Author: Fattie,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-10 21:28:22

Jeśli masz ograniczenie, aby wyśrodkować Widok stosu pionowo wewnątrz widoku przewijania, po prostu usuń go.

 0
Author: Ahmed Elashker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-10 15:57:07

Przykład dla pionowego widoku stackview/scrollview (używając EasyPeasy do autolayout):

let scrollView = UIScrollView()
self.view.addSubview(scrollView)
scrollView <- [
    Edges(),
    Width().like(self.view)
]

let stackView = UIStackView(arrangedSubviews: yourSubviews)
stackView.axis = .vertical
stackView.distribution = .fill    
stackView.spacing = 10
scrollView.addSubview(stackView)
stackView <- [
    Edges(),
    Width().like(self.view)
]

Po prostu upewnij się, że każdy z subview ' S wysokość jest zdefiniowana!

 0
Author: dOM,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-24 10:34:59
  1. Przede wszystkim zaprojektować swój widok, najlepiej w coś takiego jak szkic lub uzyskać pomysł, co chcesz jako zawartość przewijania.

  2. Po tym Ustaw kontroler widoku jako wolny formularz (wybierz z atrybutu inspektor) i ustaw wysokość i szerokość zgodnie z zawartością wewnętrzną rozmiar widoku (do wyboru z Inspektora rozmiaru).

  3. Po tym w kontrolerze widoku umieść widok przewijania i jest to logika, która moim zdaniem działa prawie cały czas w iOS (może to wymagać przejrzenia dokumentacji tej klasy widoku, którą można uzyskać za pomocą polecenia + kliknięcie na tę klasę lub 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ż widok przewijania został wprowadzone najpierw, zacznij od widoku przewijania, a następnie przejdź do na widok stosu. Tutaj umieścić ograniczenia widoku przewijania do zera we wszystkich kierunkach vis-a-vis jego super widok. Umieść wszystkie widoki w tym widoku przewijania, a następnie umieść je w widoku stosu.

Podczas pracy z widokiem stosu

  • Pierwszy start z ground up( bottoms Up approach), tj. jeśli masz etykiety, pola tekstowe i obrazy w widoku, najpierw ułóż te widoki (w widoku przewijania), a następnie umieść je w widoku stosu.

  • Po to zmienia właściwość widoku stosu. Jeśli pożądany widok nadal nie zostanie osiągnięty, użyj innego widoku stosu.

  • jeśli nadal nie osiągniesz, graj z odpornością na ściskanie lub priorytetami Przytulania treści.
  • następnie dodaj ograniczenia do widoku stosu.
  • pomyśl także o użyciu pustego widoku UIView jako widoku wypełniacza, jeśli wszystkie powyższe nie dają zadowalających rezultatów.

Po utworzeniu widoku, umieść ograniczenie między widokiem stosu macierzystego a widokiem przewijania, podczas gdy ograniczanie dzieci widok stosu z widokiem stosu matki. Mam nadzieję, że w tym czasie powinno działać dobrze lub może dostać ostrzeżenie od Xcode dając sugestie, przeczytaj, co mówi i wdrożyć te. Mam nadzieję, że teraz powinieneś mieć widok roboczy zgodnie z Twoimi oczekiwaniami:).

 0
Author: Nikhil Pandey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-26 09:26:28

Dla widoku zagnieżdżonego lub pojedynczego stosu widok przewijania musi mieć stałą szerokość z widokiem głównym. Główny widok stosu, który znajduje się wewnątrz widoku przewijania, musi ustawić tę samą szerokość. [Mój widok przewijania jest poniżej widoku ignoruj go]

Ustaw ograniczenie o jednakowej szerokości między UIStackView i UIScrollView.

Tutaj wpisz opis obrazka

 0
Author: Md Imran Choudhury,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-16 15:28:49

Włóż do UIScrollView...

 -10
Author: eik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-28 08:22:14