UIScrollView Przewijalna zawartość Rozmiar Niejednoznaczność

510

Drodzy deweloperzy, mam problem z AutoLayout w Interface Builder (Xcode 5 / iOS 7). Jest to bardzo podstawowe i ważne, więc myślę, że każdy powinien wiedzieć, jak to działa poprawnie. Jeśli jest to błąd w Xcode, jest to błąd krytyczny!

Kiedy więc mam taką hierarchię widoków, mam problemy:

>UIViewController
>> UIView
>>>UIScrollView
>>>>UILabel (or any other comparable UIKit Element)

UIScrollView ma solidne ograniczenia, np. 50 pikseli z każdej strony (bez problemu). Następnie dodaję ograniczenie górnej przestrzeni do UILabel (bez problemu) (i mogę nawet przypiąć wysokość / szerokość etykiety, nic nie zmienia, ale powinno być niepotrzebne ze względu na wewnętrzny rozmiar etykiety)

Problem zaczyna się, gdy dodam ograniczenie końcowe do UILabel:

Np. Końcowe odstępy do: Superview równa się: 25

Teraz pojawiają się dwa ostrzeżenia - i nie rozumiem, dlaczego:

A) Dwuznaczność przewijalnej zawartości (widok przewijania ma niejednoznaczną przewijaną wysokość / szerokość)

B) Niewłaściwe widoki (oczekiwana etykieta: x = -67 Rzeczywista: x = 207

Zrobiłem ten minimalny przykład w świeżo nowym projekcie, który można pobrać i załączyłem zrzut ekranu. Jak widać, Konstruktor interfejsów oczekuje, że etykieta będzie znajdować się poza granicą UIScrollView (pomarańczowy przerywany prostokąt). Aktualizacja ramki etykiety za pomocą narzędzia Rozwiąż problemy przenosi ją właśnie tam.

Uwaga: W przypadku zamiany UIScrollView na UIView zachowanie jest zgodne z oczekiwaniami (ramka etykiety jest poprawna i zgodna z ograniczeniem). Wygląda na to, że występuje problem z UIScrollView lub brakuje mi czegoś ważnego.

Kiedy uruchamiam aplikację bez aktualizacji ramki etykiety, jak sugeruje IB, jest ona pozycjonowana w porządku, dokładnie tam, gdzie powinna być, a UIScrollView można przewijać. Jeśli zaktualizuję ramkę, etykieta jest niewidoczna, a UIScrollView nie przewija się.

Pomóż mi Obi-Wan Kenobi! Dlaczego niejednoznaczny układ? Dlaczego źle umieszczony widok?

Możesz pobrać przykładowy projekt tutaj i spróbować dowiedzieć się, co się dzieje: https://github.com/Wirsing84/AutoLayoutProblem

Ilustracja problemu w Konstruktorze interfejsów

Okablowanie
źródło
8
Spróbuj umieścić UILabel w widoku zawartości, a następnie ustaw końcową krawędź etykiety na widok zawartości (zwykły UIView). Ten film może ci bardzo pomóc: youtube.com/watch?v=PgeNPRBrB18&feature=youtu.be
erdekhayser
1
Świetne wideo, ale nie naprawiło dla mnie ostrzeżeń. :(
Rogers
Dziękuję bardzo za wideo - nauczyłem się z niego dość zaskakująco dużo! Kiedy jednak połączę wiedzę o filmie z stackoverflow.com/questions/18953617/… , mogę naprawić ostrzeżenia. Pozostaje pytanie: jak sprawić, aby rozmiar contentView scrollView był tak duży, jak to konieczne?
Okablowanie
Spójrz na ten film. Pokazuje, jak korzystać z UIScrollLayout i autolayout z XCode 5 / iOS 7.
jaxvy
Moja sugestia to nie używaj UIScrollViewbezpośrednio. Zamiast tego użyj UICollectionViewlub w UITableViewjak największym stopniu, w większości przypadków wszystko jest możliwe z tym elementem, a także zapewnia prostotę, czytelność i możliwość ponownego użycia !!!
SPatel

Odpowiedzi:

1093

Po prostu uporządkowałem w ten sposób:

  1. Wewnątrz UIScrollView dodaćUIView (możemy nazwać contentView);

  2. W tym contentView, zespół górny, dolny, lewy i prawy do 0 (oczywiście z scrollViewktórym jest superView); Ustaw także wyrównaj środek w poziomie i w pionie ;

Wykończone .

Teraz można dodać wszystkie swoje poglądy na to contentView, a contentSizez scrollViewautomatycznie zostanie zmieniony zgodnie z contentView.

Aktualizacja:

Niektóre specjalne przypadki są omówione w tym filmie opublikowanym przez @Sergio w komentarzach poniżej.

Matteo Gobbi
źródło
33
Prawie idealne, z tym wyjątkiem, że widok przewijania nie może już odgadnąć długości zawartości i odpowiednio zmienić jej rozmiar, aby dopasować zawartość do obiektów. Mam widok tabeli wewnątrz contentView, którego wysokość zmienia się (przez ograniczenie), a widok przewijania nie pozwala mi na przewijanie.
CyberMew
28
Może ten film pomoże rozwiązać wszystkie pozostałe problemy.
Sergio,
46
nie powoduje to przewijania.
dorian
2
@MatteoGobbi To było to! Udało się! Walczyłem z tego rodzaju problemami z szaleństwem scrollView autoLayout przez 2 dni .... Dziękuję, stary !!!
polo987,
56
Dla każdego, kto boryka się z problemem niemożności przewijania ScrollView, ustawianie dolnej części i wyrównywanie zawartości contentView w pionie ograniczenia o niskim priorytecie pomogło mi!
jimmy0251
98

Ten błąd zajęło mi trochę czasu, aby wyśledzić, początkowo próbowałem przypiąć rozmiar ScrollView, ale komunikat o błędzie wyraźnie mówi „rozmiar zawartości”. Upewniłem się, że wszystko, co przypiąłem od góry ScrollView, było również przypięte do dołu. W ten sposób ScrollView może obliczyć wysokość zawartości, znajdując wysokość wszystkich obiektów i ograniczeń. Rozwiązało to niejednoznaczną wysokość zawartości, szerokość jest dość podobna ... Początkowo większość rzeczy X była wyśrodkowana w ScrollView, ale musiałem również przypiąć obiekty z boku ScrollView. Nie podoba mi się to, ponieważ iPhone6 ​​może mieć szerszy ekran, ale usunie błąd „niejednoznacznej szerokości treści”.

nazwa własna
źródło
31
Dziękuję za Twoją odpowiedź! Jeśli dobrze cię rozumiem, możesz usunąć błąd, przypinając każdy widok podrzędny w ScrollView do góry i do dołu. Nie jest to jednak konieczne. Musisz tylko upewnić się, że istnieje sposób na utworzenie ciągłej linii ograniczeń od góry do dołu widoku przewijania. [-XXX] Mam nadzieję, że było to zrozumiałe;>
Wirsing
1
Jak rozwiązać problem, jeśli widok ma zmienną wysokość? Jak skonfigurować wiązania, aby widok przewijania mógł obliczyć rozmiary?
hashier 24.10.2013
2
„Musisz tylko upewnić się, że istnieje sposób na stworzenie ciągłej linii ograniczeń od góry do dołu przewijania” <- dzięki za to zdanie
Adam Waite
3
Pomogło mi upewnienie się, że widok przewijania został przypięty do podglądu, a nie górny lub dolny przewodnik układu. Usunąłem ograniczenie dla dolnego przewodnika po układzie i przeszedłem przez menu zamiast konstruktora interfejsu. Editor -> Pin -> Bottom Space to Superview.
Alberto Lopez
2
Jeśli chcesz, aby szerokość widoku przewijania odpowiadała szerokości ekranu telefonu lub dowolnego innego elementu w interfejsie użytkownika (np. Zawierającego UIView), musisz ustawić na nim „równą szerokość”, używając innego elementu, który znajduje się poza widokiem przewijania.
Departamento B,
89

Xcode 11+

Najprostszy sposób przy użyciu autolayout:

  1. Dodaj UIScrollViewi 0,0,0,0przypnij do podglądu (lub żądanego rozmiaru)
  2. Dodaj UIVieww ScrollView, przypnij go 0,0,0,0do wszystkich 4 stron i wyśrodkuj horizontallyi vertically.
  3. W inspektorze rozmiarów zmień bottomi align center Ypriorytet na 250. (dla zmiany przewijania w poziomie trailingi align center X)
  4. Dodaj wszystkie potrzebne widoki do tego widoku. Nie zapomnij ustawić dolnego ograniczenia dla najniższego widoku.
  5. Wybierz UIScrollView, wybierz inspektor rozmiaru i odznacz Content Layout Guides.
Đorđe Nilović
źródło
1
Nie mogłem ustawić wysokości zawartości widoku przewijania, ale działa. :)
Blind Ninja
2
Wskazówka: według mnie działało to tylko wtedy, gdy usunąłem środek w poziomie i pionie i zastąpiłem go równą szerokością (scrollView + widok wewnątrz scrollView) ORAZ dodanie wysokości w oparciu o treść, co oznacza, że ​​ostatni element widoku wymaga ograniczenia dolnego. Zajrzyj tutaj, aby uzyskać więcej informacji: stackoverflow.com/a/54577278/5056173
Sean Stayns
1
Sean, używam tego dosłownie każdego dnia i nigdy nie miałem problemu z tym podejściem, jeśli chodzi o przewijanie widoku pionowego i poziomego. Być może zapomniałeś nałożyć dolne ograniczenie na najniższy / ostatni element. Bez tego to nie zadziała.
Norđe Nilović
7
Punkt 4 - drugie zdanie jest najważniejsze.
Nitish
2
ta odpowiedź idealnie dla mnie
działała
63

To odpowiedź na moje pytanie, na które odpowiedziałeś sam UIScrollView + widok wyśrodkowany + Ambigous przewijalny rozmiar treści + wiele rozmiarów iPhone'a .

Ale w pełni obejmuje również twoją skrzynkę!

Oto stan początkowy dla najprostszego przypadku:

  1. scrollView z 0 wiązaniami do wszystkich krawędzi
  2. Przycisk wyśrodkowany w poziomie i pionie ze stałą szerokością i wysokością ograniczeniami
  3. I oczywiście - irytujące ostrzeżenia Has ambiguous scrollable content width i Has ambiguous scrollable content height.

1

Wszystko, co musimy zrobić, to:

  • Dodaj 2 dodatkowe ograniczenia, na przykład „0” dla końcowego i / lub dolnego miejsca dla naszego widoku (spójrz na przykład na zrzucie ekranu poniżej).

Ważne: musisz dodać ograniczenia końcowe i / lub dolne . Nie „wiodące i najlepsze” - to nie działa!

2)

Możesz to sprawdzić w moim przykładowym projekcie pokazującym, jak rozwiązać ten problem.

PS

Zgodnie z logiką - działanie to powinno powodować „sprzeczne ograniczenia”. Ale nie!

Nie wiem, dlaczego to działa i jak Xcode wykrywa, które ograniczenie ma większy priorytet (ponieważ nie ustawiam priorytetu dla tych ograniczeń). Będę wdzięczny, jeśli ktoś wyjaśni, dlaczego to działa w komentarzach poniżej.

skywinder
źródło
Świetna wskazówka! Skończyło się na tym, że stworzyłem ograniczenie do dolnej krawędzi i ustawiłem priorytet na średni lub niski
Dean
Łał! To poważnie nie ma sensu, ale działa! Dziękuję Ci! Ostatni element, jaki mam, moim zdaniem, ustawiłem dolne ograniczenie na 0 i BANG. Wreszcie działało.
Jakob Hviid
60

Xcode 11+, Swift 5

Jeśli zastanawiasz się, dlaczego wszystkie odpowiedzi już nie działają, upewnij się, że przypiąłeś widok zawartości (ten, który umieściłeś w widoku przewijania) do Przewodnika po układzie treści widoku przewijania, a NIE do Przewodnika układu ramki.

Krawędzie widoku zawartości (wiodące, końcowe, górne, dolne) nie powinny być przypięte jak wiodące na obrazie - do Przewodnika po układzie ramki

Nie tak jak to

ale tak to - do Przewodnika po układzie treści.

Z menu wybierz Przewodnik po układzie treści

wprowadź opis zdjęcia tutaj

A wtedy większość odpowiedzi zadziała dla Ciebie.

Najprostsze podejście teraz wygląda następująco:

  1. Umieść widok przewijania w widoku głównym
  2. Przypnij wszystkie boki widoku przewijania do podglądu
  3. Weź inny UIView (nazywa to widokiem zawartości) i umieść go w widoku przewijania
  4. Przypnij wszystkie boki widoku zawartości, aby przewinąć Przewodnik po układzie treści widoku
  5. Przypnij szerokość widoku zawartości, aby była równa przewodnikowi układu ramki widoku
  6. Napraw wysokość widoku zawartości w dowolny sposób (użyłem tylko stałego ograniczenia wysokości w poniższym przykładzie)

Ogólna struktura w najprostszej implementacji będzie wyglądać tak

wprowadź opis zdjęcia tutaj

Chcę wiedzieć
źródło
@WantToKnow Nie trzeba ograniczać wysokości, wystarczy zmienić jej priorytet na niski (250)
Reckoner
Xcode 11+, Swift 5. Zgodnie z odpowiedzią @WantToKnow rozwiązałem swój problem, przygotowałem [wideo] [1] i [kod] [2] [1]: youtube.com/watch?v=qMrH5_Yj5hM [2]: github.com/AhmAbdallah/CustomCollectionView
Ahmed Abdallah
1
To świetna odpowiedź, dziękuję.
Constantine
1
To jest właściwa odpowiedź. Dzięki.
Vincent Joy,
Działa
49

Musisz utworzyć UIViewwidok podrzędny UIScrollViewopisanego poniżej:

  • UIViewController
  • UIView 'Główny widok'
    • UIScrollView
      • UIView „Widok kontenera”
        • [Twoja treść]

Drugim krokiem jest nałożenie UIScrollViewograniczeń. Zrobiłem to z górnymi, dolnymi, wiodącymi i końcowymi ograniczeniami jego superView.

Następnie dodałem ograniczenia dla kontenera UIScrollViewi tutaj zaczyna się problem. Gdy nałożysz te same ograniczenia (górny, dolny, wiodący i końcowy), Storyboard wyświetli komunikat ostrzegawczy:

„Ma niejednoznaczną przewijalną szerokość zawartości” i „Ma niejednoznaczną przewijalną zawartość”

Kontynuuj z tymi samymi ograniczeniami powyżej i po prostu dodaj ograniczenia Equal Heighti Equal Widthdo swojego widoku kontenera w stosunku do widoku głównego, a nie do twojego UIScrollView. Innymi słowy, ograniczenia widoku kontenera są powiązane z UIScrollViewnadzorem.

Po tym nie będziesz mieć ostrzeżeń w swoim Storyboard i możesz kontynuować dodawanie ograniczeń dla swoich podstron.

Thiago Monteiro
źródło
2
Uzgodnione - myślę, że dodanie widoku kontenera jest najlepszym, najbardziej konserwowalnym rozwiązaniem.
Andrew Ebling
1
To rozwiązanie będzie działać, gdy nie masz paska nawigacji do zarządzania.
Leena,
25

Miałem ten sam problem. Odznacz to pole wyboru. Ponieważ ustawiasz rozmiar zawartości w kodzie. wprowadź opis zdjęcia tutaj

Jodagama
źródło
24

W końcu to rozgryzłem, mam nadzieję, że łatwiej to zrozumieć.

Często można ominąć to ostrzeżenie, dodając podstawowy widok UIView do widoku przewijania jako „widok zawartości”, jak wspomniano, i nadając mu taki sam rozmiar jak widok przewijania oraz, w tym widoku zawartości, ustaw te 6 parametrów.

wprowadź opis zdjęcia tutaj

Jak widać, potrzebujesz 6 parametrów ogółem! Które .. w normalnych okolicznościach duplikujesz 2 ograniczenia, ale jest to sposób na uniknięcie tego błędu w serii ujęć.

William T.
źródło
1
Powyższe prawie dla mnie zadziałało, ponieważ martwię się o 3 różne szerokości ekranu (4/5, 6, 6+) Ustawiam widok zawartości i widok przewijania, aby miały równe szerokości. Masz rację, jest to duplikat, ponieważ już powiedziałem widokowi treści, że ma 0 początkowej i końcowej spacji.
Stuart P.
8
Zamiast stałych wartości można ustawić równe ograniczenia szerokości i wysokości z widoku treści do widoku przewijania. Będzie to działać na wszystkich rozdzielczościach.
Kumar C
Muszę zaimplementować to samo, więc możesz mi pomóc, że muszę ustawić jednakową wysokość i szerokość zarówno dla widoku zawartości, jak i widoku przewijania?
Urmi
Może warto sprawdzić, czy nadal musisz to zrobić. Ostatnio skonfigurowałem imageView w widoku przewijania i udało mi się uciec, ustawiając tylko 4 ograniczenia pokazane u góry, aby błąd zniknął w Xcode 8.3
William T.
1
@ Kochanie zostało opublikowane ponad 3 lata temu. Od tego czasu zdecydowanie poprawili scenorysy. Zauważyłem też, że możesz teraz uciec bez widoku zawartości. Dostosuję swoją odpowiedź.
William T.
16

Wiem, że mogę się spóźnić, ale następne rozwiązanie rozwiązuje tego rodzaju problemy bez dodatkowego kodu , używając tylko scenariuszy:

W widoku zawartości musisz ustawić ograniczenia dla spacji wiodących / końcowych / górnych / dolnych, aby przewijać widok, a to nie zmieni ramki widoku , tak jak to:wprowadź opis zdjęcia tutaj

Oczywiście musisz utworzyć dodatkowe ograniczenia dla widoku zawartości, aby widok przewijania mógł znać rozmiar zawartości. Na przykład ustaw stałą wysokość i środek x.

Mam nadzieję że to pomoże.

Borzh
źródło
7

Dla mnie dodanie contentViewnie działało tak, jak sugerowano. Co więcej, tworzy dodatkowy koszt z powodu dodanego widoku (chociaż nie uważam tego za duży problem). Dla mnie najlepsze było wyłączenie sprawdzania niejednoznaczności w moim przypadku scrollView. Wszystko układa się ładnie, więc myślę, że w prostych przypadkach, takich jak moje, jest w porządku. Pamiętaj jednak, że jeśli inne ograniczenia związane z scrollViewprzerwą, Konstruktor interfejsów nie będzie Cię więcej ostrzegać.

wprowadź opis zdjęcia tutaj

Nick Podratz
źródło
5
Spowoduje to usunięcie ostrzeżenia i nie spowoduje rozwiązania problemu.
Predrag Manojlovic
Ty. są. mój. bohater. Nie zdawałem sobie sprawy, że to istnieje i cieszę się, że to znalazłem! Próbowałem „Weryfikuj tylko pozycję”, czego można oczekiwać, nie wiem, weryfikuj tylko pozycję, ale nie, pozwala to również na ten problem z błędem „rozmiaru zawartości”. Muszę iść z „Never Verify”. Dzięki!
Dustin
Myślę, że to właściwa odpowiedź, jeśli programowo tworzysz widok dziecka. Dzięki!
Florian Kusche
3

Patrz poniżej: widok zawartości w widoku przewijania scentralizowany w pionie i poziomie. masz błąd niejednoznaczności, zawsze upewnij się, że dwa dodane do widoku przewijania z widoku zawartości to 1). spacja do kontenera 2) spacja do ograniczenia, która jest podświetlona na zrzucie ekranu,

Ograniczenie to oznacza, że ​​w przewijaniu można przewijać po wysokości lub szerokości widoku zawartości.

wprowadź opis zdjęcia tutaj

to może ci pomóc.

Ravi Kumar
źródło
3

Rozwiązałem ten problem dla mojego widoku, używając opcji „Rozwiąż problemy z automatycznym układem”> „Dodaj brakujące ograniczenia” dla wybranego widoku wprowadź opis zdjęcia tutaj

Następujące dwa ograniczenia rozwiązują mój problem:

trailing = Stack View.trailing - 10
bottom = Stack View.bottom + 76

w którym: końcowe, dolne to końcowe, dolne z UIScrollView

Linh Dao
źródło
To działało dla mnie, dodając ograniczenie „do dołu”. Teraz, gdy o tym myślę, ma to sens.
SilverWolf - Przywróć Monikę
3

Korzystanie z contentView (UView ) jako środka pojemnika UIScrollView, kij do krawędzi ( top, bottom, trailing, leading) z SuperView ( UIScrollView) i contentViewpowinien mieć equalwidthi equalheightdo SuperView. To są ograniczenia. I wywołanie metody:

-(void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    self.scrollView.contentSize = self.contentView.frame.size;
}

Rozwiązane problemy dla mnie.

Spiridon Kopicl
źródło
3

Podejście Swift 4+:

1) Ustaw UIScrollView górny, dolny, lewy i prawy margines na 0

2) Wewnątrz UIScrollView dodaj UIView i ustaw górny, dolny, wiodący, końcowy margines na 0 (równy marginesom UIScrollView).

3) Najważniejsze jest ustawienie szerokości i wysokości, gdzie ograniczenie wysokości powinno mieć niski priorytet .

private func setupConstraints() {

    // Constraints for scrollView
    scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

    // Constraints for containerView
    containerView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
    containerView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
    containerView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
    containerView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
    containerView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true

    let heightConstraint = containerView.heightAnchor.constraint(equalTo: scrollView.heightAnchor)
    heightConstraint.priority = UILayoutPriority(rawValue: 250)
    heightConstraint.isActive = true
}
Gentian Sadiku
źródło
2

@Matteo Gobbi odpowiedź jest idealna, ale w moim przypadku widok przewijania nie może się przewijać, usuwam „ wyrównaj środek Y ” i dodaję „ wysokość> = 1 ”, przewijanie stanie się przewijalne

ygweric
źródło
2

Osoby, które borykają się z uiscrollview, a nie przewijaniem, po prostu ustawiają dolne ograniczenie widoku zawartości za pomocą dolnego układu ostatniego widoku (który znajduje się wewnątrz widoku zawartości). Nie zapomnij usunąć ograniczenia Y środka.

Reszta wszystkie ograniczenia są takie same, jak zdefiniowano powyżej. Scrollview martwi się tylko o uzyskanie maksymalnej wysokości z widoku zawartości, a my ustawiamy go jako ograniczenie dolne ostatniego widoku, co oznacza, że ​​scrollview automatycznie zmieni przesunięcie zawartości.

W moim przypadku ostatni widok był UILable z właściwością nr linii = 0 (która automatycznie dostosowuje jego wysokość w zależności od jego zawartości), więc dynamicznie zwiększa wysokość uilable, a ostatecznie nasz przewijany obszar zwiększa się z powodu układu dolnego uilable jest wyrównany z dolnym widokiem naszego treści, co zmusza scrollview do zwiększenia przesunięcia zawartości.

Siddhesh Mahadeshwar
źródło
2

Zrobiłem wideo na youTube
youTube Scroll StackViews używając tylko Storyboard w Xcode

Myślę, że mogą się tu pojawić 2 rodzaje scenariuszy.

Widok wewnątrz scrollView -

  1. nie ma żadnej wewnętrznej treści Rozmiar (np. UIView)
  2. ma swoją własną treść Rozmiar (np. UIStackView)

Aby przewijać w pionie widok w obu przypadkach, musisz dodać te ograniczenia:

  1. 4 ograniczenia od góry, lewej, dołu i prawej.

  2. Równa szerokość do przewijania (aby zatrzymać przewijanie w poziomie)

Nie potrzebujesz żadnych innych ograniczeń dla widoków, które mają własną wewnętrzną wysokość treści.

wprowadź opis zdjęcia tutaj


W widokach, które nie mają żadnej wewnętrznej wysokości treści, należy dodać ograniczenie wysokości. Widok będzie przewijany tylko wtedy, gdy ograniczenie wysokości jest większe niż wysokość scrollView.

wprowadź opis zdjęcia tutaj

Warif Akhand Rishi
źródło
2
import UIKit

class ViewController: UIViewController {

    //
    let scrollView: UIScrollView = {

        let sv = UIScrollView()
        sv.translatesAutoresizingMaskIntoConstraints = false
        return sv
    }()

    let lipsumLbl: UILabel = { // you can use here any of your subview

        let lbl = UILabel()
        lbl.translatesAutoresizingMaskIntoConstraints = false
        lbl.text = """
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce eleifend nisi sit amet mi aliquet, ut efficitur risus pellentesque. Phasellus nulla justo, scelerisque ut libero id, aliquet ullamcorper lectus. Integer id iaculis nibh. Duis feugiat mi vitae magna tincidunt, vitae consequat dui tempor. Donec blandit urna nec urna volutpat, sit amet sagittis massa fringilla. Pellentesque luctus erat nec dui luctus, sed maximus urna fermentum. Nullam purus nibh, cursus vel ex nec, pulvinar lobortis leo. Proin ac libero rhoncus, bibendum lorem sed, congue sapien. Donec commodo, est non mollis malesuada, nisi massa tempus ipsum, a varius quam lorem vitae nunc.

        Cras scelerisque nisi dolor, in gravida ex ornare a. Interdum et malesuada fames ac ante ipsum primis in faucibus. Maecenas vitae nisl id erat sollicitudin accumsan sit amet viverra sapien. Etiam scelerisque vulputate ante. Donec magna nibh, pharetra sed pretium ac, feugiat sit amet mi. Vestibulum in ipsum vitae dui vehicula pulvinar eget ut lectus. Fusce sagittis a elit ac elementum. Fusce iaculis nunc odio, at fermentum dolor varius et. Suspendisse consectetur congue massa non gravida. Sed id elit vitae nulla aliquam euismod. Pellentesque accumsan risus dolor, eu cursus nibh semper id.

        Vestibulum vel tortor tellus. Suspendisse potenti. Pellentesque id sapien eu augue placerat dictum. Fusce tempus ligula at diam lacinia congue in ut metus. Maecenas volutpat tellus in tellus maximus imperdiet. Integer dignissim condimentum lorem, id luctus nisi maximus at. Nulla pretium, est sit amet mollis eleifend, tellus nulla viverra dolor, ac feugiat massa risus a lectus. Pellentesque ut pulvinar urna, blandit gravida ipsum. Nullam volutpat arcu nec fringilla auctor. Integer egestas enim commodo, faucibus neque ac, rutrum magna. Vivamus tincidunt rutrum auctor. Cras at rutrum felis. Fusce elementum lorem ut pharetra venenatis.
        """
        lbl.textColor = .darkGray
        lbl.font = UIFont.systemFont(ofSize: 16)
        lbl.numberOfLines = 0
        return lbl
    }()

    //======================================================================//
    //
    // MARK:- viewDidLoad
    //
    override func viewDidLoad() {
        super.viewDidLoad()

        setupViews()
        setupAutoLayout()
    }

    func setupViews() {

        title = "ScrollView Demo"
        view.backgroundColor = .white
        view.addSubview(scrollView)
        scrollView.addSubview(lipsumLbl)
    }

    func setupAutoLayout() {

        scrollView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        scrollView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

        lipsumLbl.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
        lipsumLbl.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
        lipsumLbl.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        lipsumLbl.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        lipsumLbl.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
    }
}

Wynik:

wprowadź opis zdjęcia tutaj

iAj
źródło
dlaczego potrzebujesz LeadAnchor, skoro już go opuściłeś?
ShadeToD,
leftAnchor nie może być użyty do tego celu, więc musimy użyć wiodącegoAnchor do osiągnięcia tego samego ...
iAj 14.10.19
użyłeś obu w swoim przykładzie.
ShadeToD,
@ShadeToD pozwól mi sprawdzić
iAj
2

W moim przypadku pojawił się problem z nieprawidłowym rozmiarem i rozmiarem treści w iPadzie, ale działał w przypadku iPhone'a. Zrobiłem następujące zmiany w scenorysie, aby rozwiązać problem.

  1. Dodaj widok przewijania w UIView i dodaj ograniczenia wiodące, górne, końcowe i dolne do 0,0,0,0.
  2. Ustaw wysokość widoku przewijania zgodnie z wymaganiami dla np. 100
  3. Dodaj UIView, aby przewijać widok i dodać wiązania wiodące, górne, końcowe i dolne do 0,0,0,0 i wyrównać wiązania środkowe (X) i środkowe (Y).
  4. Usuń zaznaczenie „Przewodników układu treści” w inspektorze rozmiaru widoku przewijania.
Daljeet Seera
źródło
1

Przewijanie pionowe

  1. Dodaj UIScrollView z ograniczeniami 0,0,0,0 do podglądu.
  2. Dodaj UIView w ScrollView, z ograniczeniami 0,0,0,0 do podglądu.
  3. Dodaj to samo ograniczenie szerokości dla UIView do UIScrollView.
  4. Dodaj wysokość do UIView.
  5. Dodaj elementy z ograniczeniami do UIView.
  6. W przypadku elementu znajdującego się najbliżej dna upewnij się, że ma on ograniczenie do dolnej części UIView.
Bitcon
źródło
0

To, co zrobiłem, to utworzenie osobnego widoku zawartości, jak pokazano tutaj.

Widok zawartości jest dowolny i można do niego dodać wszystkie widoki podrzędne z własnymi ograniczeniami w stosunku do contentView.

UIScrollView jest dodawany do głównego kontrolera widoku.

Programowo dodaję contentView, który jest połączony przez IBOutlet, do klasy i ustawiam contentView UIScrollView.

UIScrollView z ContentView za pomocą Konstruktora interfejsów

Vlad
źródło
0

Otrzymałem ten sam błąd .. zrobiłem następujące

  1. Zobacz (Superview)
  2. ScrollView 0,0,600,600
  3. UIView wewnątrz ScrollView: 0,0,600,600
  4. UIView zawiera widok obrazu, etykietę

Teraz dodaj wiodące / końcowe / górne / dolne dla scrollView (2), a następnie UIView (3).

Wybierz Widok (1) i Widok (3) ustaw jednakowy wzrost i wagę .. to rozwiązało mój problem.

Zrobiłem wideo, które pomoże:

https://www.youtube.com/watch?v=s-CPN3xZS1A

Vinod Joshi
źródło
0

[testowany w XCode 7.2 i na iOS 9.2]

Tym, co tłumiło błędy i ostrzeżenia Storyboard dla mnie, było ustawienie wewnętrznego rozmiaru widoku przewijania i widoku zawartości (w moim przypadku widoku stosu) na Placeholder . To ustawienie znajduje się w Inspektorze rozmiarów w Storyboard. I mówi: - Ustawienie wewnętrznego rozmiaru treści podczas projektowania wpływa tylko na widok podczas edycji w Konstruktorze interfejsów. Widok nie będzie miał tego rzeczywistego rozmiaru treści w czasie wykonywania.

Więc myślę, że nie popełnimy błędu, ustawiając to.

Uwaga: W serii ujęć przypiąłem wszystkie krawędzie widoku przewijania do podglądu i wszystkie krawędzie widoku stosu do widoku przewijania. W moim kodzie ustawiłem translatesAutoresizingMaskIntoConstraints na wartość false zarówno dla widoku przewijania, jak i widoku stosu. I nie wspominałem o wielkości treści. Gdy widok stosu rośnie dynamicznie, ograniczenia ustawione w serii ujęć zapewniają przewijanie stosu.

Ostrzeżenie w scenariuszu doprowadzało mnie do szaleństwa i nie chciałem centrować rzeczy poziomo lub pionowo tylko po to, aby je ostrzec.

gtl_pm
źródło
0

Jeśli ktoś dostaje zachowanie, w którym zauważysz pasek przewijania po prawej stronie, ale treść się nie porusza, ten fakt prawdopodobnie warto rozważyć:

Można także użyć ograniczeń między zawartością widoku przewijania a obiektami poza widokiem przewijania, aby zapewnić stałe położenie zawartości widoku przewijania, dzięki czemu treść wydaje się unosić nad widokiem przewijania.

To z dokumentacji Apple . Na przykład, jeśli przypadkowo przypiąłeś swoją górną etykietę / przycisk / obraz / widok do widoku poza obszarem przewijania (może nagłówek lub coś tuż nad scrollView?) Zamiast contentView, zamrozisz całą contentView na swoim miejscu.

Dave G.
źródło
0

Jak wspomniano w poprzednich odpowiedziach, należy dodać widok niestandardowy w widoku przewijania:

Widok niestandardowy to ContentView oznaczony na obrazie

Dodaj wszystkie swoje widoki podrzędne do widoku treści. W pewnym momencie zobaczysz, że przewijany widok treści ma niejednoznaczne ostrzeżenie o rozmiarze zawartości, powinieneś wybrać widok zawartości i kliknąć przycisk „Rozwiąż problemy z automatycznym układem” (w prawym dolnym rogu układu IB) i wybierz „Dodaj brakujące ograniczenia ”.

wprowadź opis zdjęcia tutaj

Od teraz, kiedy uruchomisz projekt, widok przewijania automatycznie zaktualizuje jego rozmiar zawartości, bez dodatkowego kodu.

supergegs
źródło
0

Musisz tylko upewnić się, że istnieje sposób na utworzenie ciągłej linii ograniczeń od góry do dołu widoku przewijania. [-XXX]

W moim przypadku - przewijany w poziomie widok przewijania - musiałem również dodać ograniczenia szerokości i wysokości dla każdego elementu potomnego widoku przewijania, chociaż uwaga techniczna Apple tego nie mówi.

johnnyMac
źródło
0

Jeśli nadal masz problemy z UIScrollView, po prostu wyłącz Przewodniki układu treści (wybierz ScrollView w Xcode Interface Builder -> wybierz Inspektor rozmiarów w prawym panelu -> odznacz „Przewodniki układu treści”) lub spróbuj wykonać następujące czynności: xcode 11 układów przewijania widoku - może być przydatny w nowym stylu układu. Działa dobrze w macOS 10.15.2, Xcode 11.3.1, na 05.02.2020

patrz zrzut ekranu

Victor Doshenko
źródło
0

Korzystanie z autolayout

Dodaj widok przewijania w dobrze zdefiniowanym widoku, a następnie dodaj widok stosu w widoku przewijania

Dodaj ograniczenia górny, lewy, prawy, dolny, środkowy X i środkowy Y z widoku przewijania i widoku stosu do odpowiednich super widoków

Upewnij się, że ograniczenia są połączone z widoku stosu do prawowitego podglądu (scrollview), ponieważ bieżącym ustawieniem domyślnym jest dodanie ograniczenia Wyrównaj górne, a nie górne spację.

Ahmed Elashker
źródło