Chociaż UIScrollView
w przeszłości z powodzeniem korzystałem z niego, manipulując nim programowo, mam problem z uruchomieniem go, konfigurując go wyłącznie w Interface Builder.
Mam prostą stronę „informacje” w mojej aplikacji na iPhone'a. Ma UITextView
kilka ikon i łącza do innych moich aplikacji. Dodałem wszystkie te widoki do mojego UIScrollView
, układając je tak, aby ich łączny rozmiar wynosił> 480. Kiedy uruchamiam moją aplikację, widok przewijania wyświetla tylko zawartość, która mieści się na ekranie i nic się nie przewija.
Czy można to zrobić całkowicie przez IB, czy też muszę manipulować contentSize za pomocą kodu?
źródło
contentSize
typeSize
i ustawiając żądaną wartość.contentSize
przewijania na podstawie wymiarów jego podglądów podrzędnych , przynajmniej jako zachowanie domyślne.Odpowiedź Boby_Wana dała mi do myślenia i znalazłem następujące rozwiązanie do skonfigurowania contentSize UIScrollView z Interface Builder:
UIScrollView
w scenie StoryboardcontentSize
Size
np. ustawienie wartości na {320, 920} pozwoli użytkownikowi przewinąć w dół cały dodatkowy ekran na iPhonie.
(Używam xcode 4.3.3, docelowy cel wdrożenia systemu iOS w projekcie to 5.1)
Kiedy wykonałem to po raz pierwszy, otrzymałem następujący błąd:
Jeśli również pojawi się ten błąd, można go łatwo naprawić: wybierz Storyboard w Nawigatorze projektu i wywołaj Inspektora plików . Znajdź / rozwiń sekcję Interface Builder Document , a pojawi się lista rozwijana dla programowania . Upewnij się, że jest to ustawione na
Xcode 4.3
źródło
"this class is not key value coding-compliant for the key keyPath"
czy możesz mi pomóc, co robię źle? Należy pamiętać, że używam xamarin-ios-c #Dzięki Autolayout (iOS6 +) możesz uniknąć ustawiania
contentSize
. Zamiast tego ustaw następujące ograniczenia:źródło
contentSize
nie działa z Xcode 5 i iOS 7Możesz to zrobić za pomocą samego Interface Builder, przejść do Inspektora tożsamości (trzecia zakładka inspektora) i dodać nowy atrybut User Defined Runtime z
źródło
Teraz jest sposób na zrobienie
UIScrollView
zwoju bez opuszczania Storyboard :UIScrollView
w Storyboard, przejdź do Inspektora rozmiaru i zmień Dolną wartość (lub jakąkolwiek inną wartość, którą musisz zmienić) w sekcji Wstawki zawartości na wysokość obszaru zawartości.contentSize
. Nie ma znaczenia, jaki typ lub wartość wpiszesz (możesz nawet zostawić ich wartość domyślną).To sprawi, że będzie
UIScrollView
działać poprawnie, chociaż nie wiem, dlaczego drugi krok jest konieczny (przypadkiem się dowiedziałem). :(źródło
Jednym z podejść, które stosowałem w przeszłości, jest przeciągnięcie widoku przewijania poza jego widok w narzędziu do tworzenia interfejsu i ustawienie jego rzeczywistego rozmiaru na taki, jaki ma mieć rozmiar contentSize.
co nie jest z natury oczywiste w konstruktorze interfejsów to to, że możesz mieć niepowiązane widoki, które są przechowywane w końcówce, ale nie są częścią widoku głównego, dla którego jest ona przeznaczona.
w widoku, w którym chcesz, aby przewijany widok był aktywny, umieść prosty UIView, którego używasz jako miejsca. (po prostu możesz wizualnie zaprojektować jego lokalizację. Jeśli używasz tylko całego widoku, możesz pominąć ten krok i użyć drugiego fragmentu kodu, który podam na końcu tej odpowiedzi).
możesz następnie wypełnić widok przewijania kontrolkami, wizualnie układając go tak, jak chcesz. podaj zarówno symbol zastępczy, jak i właściwości widoku przewijania w kontrolerze widoku, aby uzyskać do nich dostęp w czasie wykonywania.
w czasie wykonywania, w - (void) viewDidLoad
alternatywnie (jeśli nie użyłeś symbolu zastępczego):
na koniec, jeśli „zgubisz” widok przewijania w konstruktorze interfejsu (można go zamknąć, aby zniknął z siatki projektu), nie panikuj. po prostu kliknij go na liście obiektów po lewej stronie siatki projektu.
źródło
W Xcode 4.5 używającym Autolayout nie mam sekcji Wstawki zawartości w moim Inspektorze rozmiaru. Musiałem więc dodać go do atrybutów środowiska wykonawczego zdefiniowanych przez użytkownika, a potem działało dobrze.
To, co dodajesz w „atrybutach środowiska wykonawczego zdefiniowanych przez użytkownika”, to keyPath == contentInset, który jest typu „Rect” (UIEdgeInsets, który ma to samo wejście co Rect) i jest zdefiniowany jako {top, left}, {bottom, right}. ContentSize definiuje tylko region okna scrollview. contentInset definiuje przewijalny obszar.
Mam nadzieję, że to pomoże komuś w tej samej sytuacji.
źródło
Wiele z powyższych odpowiedzi jest mylących lub nieaktualnych. Począwszy od 2017 roku (prawdopodobnie znacznie wcześniej) Interfejs budowniczy robi scrollviews wsparcia z automatycznie wielkości zawartości. Sztuczka polega na tym, że XCode nadaje specjalne, niestandardowe znaczenie ograniczeniom między widokiem przewijania a zawartością w nim. Te „wewnętrzne” ograniczenia w rzeczywistości nie wpłyną na rozmiar treści, jak można by się spodziewać.
Oznacza to, że możesz np. Przypiąć widok przewijania do dołu głównego widoku z zerowym marginesem, a także przypiąć zawartość widoku przewijania do dołu widoku przewijania z zerowym marginesem, ale zawartość nie zostanie w rzeczywistości przez to rozciągnięta. Zamiast tego zawartość otrzyma swój własny rozmiar (więcej poniżej) i będzie to również rozmiar przewijalnego obszaru w przewijanym widoku.
Pomyśl o tym w ten sposób - istnieje asymetria w wiązaniu ograniczeń z widokiem przewijania: ograniczenia od widoku przewijania do świata „zewnętrznego” (nadrzędnego) określają rozmiar i położenie widoku przewijania, jak zwykle. Jednak ograniczenia „wewnątrz” widoku przewijanego w rzeczywistości określają rozmiar i położenie przewijalnego obszaru widoku przewijanego, wiążąc go z treścią.
Jest to całkowicie nieoczywiste, ponieważ kiedy idziesz do ustawiania ograniczeń, XCode zawsze zasugeruje bieżące odstępy i może nigdy nie przyjść do głowy celowa zmiana ograniczeń skierowanych do wewnątrz i na zewnątrz w sposób powodujący konflikty. Ale możesz i mają znaczenie opisane powyżej: jeden kontroluje układ widoku przewijania, a drugi kontroluje rozmiar przewijalnego obszaru zawartości.
Natknąłem się na to przez przypadek, a potem widząc, jak wyglądało to działa, doprowadziło mnie do tego artykułu, który wyjaśnia to całkowicie i cytuje źródło dokumentów Apple:
https://spin.atomicobject.com/2014/03/05/uiscrollview-autolayout-ios/
Ostatnia krytyczna informacja na temat rozmiaru treści, który sam się określił: Możesz odnieść wrażenie, że znajdujesz się w punkcie 22, ponieważ zwykle dostosowujesz rozmiar treści do np. Szerokości widoku nadrzędnego, ale w tym przypadku nadrzędnym jest widok przewijania i jak opisano powyżej - ograniczenie nie wpłynie na rozmiar zawartości. Odpowiedź jest taka, aby pamiętać, że możesz ograniczyć pozycje do elementów, które nie są bezpośrednio sąsiadujące w twojej hierarchii widoku: np. Możesz ustawić szerokość widoku zawartości na szerokość widoku głównego zamiast na próżno próbować uzyskać widok przewijania, aby to zrobić dla Ciebie.
źródło
Jeśli klikniesz ikonę Właściwości dowolnego kontrolera widoku w programie Interface Builder, możesz ustawić go na „Dowolny” rozmiar w Symulowane metryki i zmienić rozmiar głównego widoku na żądany rozmiar zawartości.
W ten sposób możesz utworzyć zawartość swojego ScrollView tak, jakby była jednym dużym widokiem. Ponieważ jest to tylko symulowana metryka, rozmiar kontrolera widoku zostanie zmieniony do granic okna po załadowaniu.
źródło
Konfigurowanie UIScrollView za pomocą Interface Builder nie jest intuicyjne. Oto moja lista kontrolna, jak ją skonfigurować:
Wybierz plik XIB UIViewControllera. W „Inspektorze tożsamości” konstruktora interfejsu zmień UIView na typ klasy UIScrollView
W sekcji „Inspektor plików” usuń zaznaczenie opcji Automatyczne układanie
W sekcji „Inspektor atrybutów” zmień rozmiar na Dowolny. Następnie możesz ręcznie rozciągnąć widok przewijania lub możesz określić niestandardową szerokość i wysokość w „Inspektorze rozmiaru”.
W „Inspektorze tożsamości” dodaj nowy atrybut wykonawczy zdefiniowany przez użytkownika o nazwie „contentSize” typu „Size” i zmień go na wartość taką jak {320, 1000}. Nie można już ustawić tego programowo i dlatego potrzebny jest ten krok, aby widok przewijania wiedział, że zawartość widoku przewijania jest większa niż okno.
źródło
Po prostu usuń autoLayout z widoku przewijania. wtedy kod jest tak prosty:
wystarczy utworzyć właściwość iboulet w pliku .h, a następnie zsyntetyzować w pliku .m. Upewnij się, że przewijanie jest włączone.
źródło
Tak, st3fan ma rację, należy ustawić właściwość contentSize UIScrollView. Nie należy jednak w tym celu wyłączać automatycznego układu. Możesz łatwo ustawić contentSize UIScrollView z automatycznym układem tylko w IB, bez żadnego kodu.
Ważne jest, aby zrozumieć, że podczas korzystania z autoukładania content Rozmiar elementu UIScrollView nie jest ustawiany bezpośrednio, jest on obliczany na podstawie ograniczeń wszystkich widoków podrzędnych UIScrollView. Wszystko, czego potrzebujesz, to zapewnienie odpowiednich ograniczeń dla widoków podrzędnych dla obu kierunków.
Np. Jeśli masz tylko jeden podgląd podrzędny, możesz ustawić jego wysokość i przestrzeń od góry i od dołu do superviewu (czyli scrollView w naszym przypadku). ContentSize.height jest obliczana jako suma
contentSize.width jest obliczana podobnie na podstawie ograniczeń poziomych.
Jeśli jest zbyt mało ograniczeń do obliczenia contentSize, mały czerwony przycisk jest wyświetlany obok elementu View Controller Scene informując o niejednoznaczności układu.
Jeśli istnieje wiele subviews to może być „łańcuch” ograniczeń: od góry do najwyższych wysokościach podrzędny, a przestrzenie między subviews i najniżej podrzędny do dołu jak w Danyal Aytekin odpowiedź.
Ale w praktyce w większości przypadków wygodniej jest po prostu dodać pusty widok o wymaganym rozmiarze i ustawić spacje na górze, po lewej, na dole i po prawej stronie scrollView na 0. Możesz używać tego widoku jako "widoku zawartości" tj. Umieścić wszystkie inne podwidoki na nim lub jeśli masz już wiele widoków podrzędnych i nie chcesz ich przenosić i ponownie konfigurować układu, możesz dodać ten widok pomocniczy do istniejących widoków podrzędnych i ukryć go.
Aby umożliwić przewijanie scrollView obliczonej zawartości, rozmiar musi być większy niż rozmiar scrollView.
źródło
Możesz mieć UIScrollView w StoryBoard z Autolayouts. Zasadniczo potrzebujesz:
źródło
Oto rozwiązanie umożliwiające zaprojektowanie ScrollView z zawartością większą niż ekran w całości w Storyboard (cóż, prawie całkowicie, musisz też dodać 1 pojedynczy wiersz kodu)
https://stackoverflow.com/a/19476991/1869369
źródło
Znajduję wygodniejszy sposób.
1: Skaluj rozmiar widoku przewijania, aby zawierał cały interfejs użytkownika w nim.
2: Dodaj iboutlet widoku przewijania.
3: W viewDidLoad zapisz rozmiar ramki widoku przewijania.
(np. _scrollSize = _scrollView.frame.size;)
4: W viewWillAppear ustaw contentSize na CGSize, który zapisałeś wcześniej.
(np. _scrollView.contentSize = _scrollSize;)
5: Done ~
źródło
źródło
Utwórz nowy projekt Xcode
Przejdź do pliku Main.storyboard
Wybierz ScrollView z biblioteki obiektów.
Ustaw ramkę dla ScrollView.
Dodaj kolejny widok, aby przewijać widok i zachować tę samą ramkę, co w ScrollView.
Teraz, aby dynamicznie ustawić jego wysokość i szerokość, możesz to skonfigurować UIScrollView przy użyciu automatycznego układu w XIB
źródło