Mam jeden, UIScrollView
który zawiera wiele UIImageView
s, UILabels itp ... etykiety są znacznie dłuższe niż te UIScrollView
, ale kiedy uruchamiam aplikację, nie mogę kliknąć i przewinąć w dół ...
Dlaczego tak się dzieje?
Dzięki
ios
iphone
ipad
uiscrollview
znak
źródło
źródło
Odpowiedzi:
Zawsze dobrze jest pokazać cały działający fragment kodu:
// in viewDidLoad (if using Autolayout check note below): UIScrollView *myScrollView; UIView *contentView; // scrollview won't scroll unless content size explicitly set [myScrollView addSubview:contentView];//if the contentView is not already inside your scrollview in your xib/StoryBoard doc myScrollView.contentSize = contentView.frame.size; //sets ScrollView content size
Swift 4.0
let myScrollView let contentView // scrollview won't scroll unless content size explicitly set myScrollView.addSubview(contentView)//if the contentView is not already inside your scrollview in your xib/StoryBoard doc myScrollView.contentSize = contentView.frame.size //sets ScrollView content size
Nie znalazłem sposobu na ustawienie contentSize w IB (od Xcode 5.0) .
Uwaga: jeśli używasz Autolayout, najlepszym miejscem na umieszczenie tego kodu jest wewnątrz
-(void)viewDidLayoutSubviews
metody.źródło
myScrollView.delegate = self
TAKŻE, jeśli to nadal nie działa, odpowiedź poniżej tej ma ŚWIETNĄ radę (przejdź do swojego xib / StoryBoard i upewnij się, że "AutoLayout" jest wyłączone). Porada od profesjonalistów: Możesz również dołączyć<UIScrollViewDelegate>
do pliku .h, jeśli chcesz wykonywać takie czynności, jak programowe przewijanie UIScrollView.viewDidLayoutSubviews
sprawiło, że zadziałało.Jeśli nie możesz przewinąć widoku nawet po prawidłowym ustawieniu contentSize , upewnij się, że odznaczyłeś "Użyj autoukładu" w Interface Builder -> File Inspector.
źródło
Musisz ustawić
contentSize
właściwość widoku przewijania, aby przewijał się prawidłowo.Jeśli używasz autoLayout, trzeba ustawić
contentSize
sięviewDidLayoutSubviews
w celu użycia go do stosowania po dopełnia autoLayout.Kod mógłby wyglądać tak:
-(void)viewDidLayoutSubviews { // The scrollview needs to know the content size for it to work correctly self.scrollView.contentSize = CGSizeMake( self.scrollContent.frame.size.width, self.scrollContent.frame.size.height + 300 ); }
źródło
contentSize
na rozmiarcontentView
, rozmiar scrollView i contentView wydaje się być ustawiony jako taki sam. Ale ustawienie wysokości nacontentSize
wartość większą niż wysokośćcontentView
zadziałało.viewDidLayoutSubviews
mogą być wywoływane wiele razy w trakcie cyklu życia, więc ryzykujesz, że zwiększysz wysokość większą niż oczekiwano.Powyższa odpowiedź jest prawidłowa - aby przewijać się, konieczne jest ustawienie rozmiaru treści.
Jeśli używasz konstruktora interfejsu, dobrym sposobem na to jest użycie atrybutów wykonawczych zdefiniowanych przez użytkownika. Na przykład:
źródło
Spróbuj zmienić rozmiar zawartości do ogromnych liczb. Nie mogłem zrozumieć, dlaczego mój widok przewijania nie przewija się, nawet jeśli rozmiar jego zawartości wydaje się być większy niż rozmiar kontrolny. Odkryłem, że jeśli rozmiar zawartości jest mniejszy niż potrzebny, to również nie działa.
self.scrollView.contentSize = CGSizeMake(2000, 2000);
Zamiast 2000 możesz umieścić własne duże liczby. A jeśli to działa, oznacza to, że rozmiar zawartości nie jest wystarczająco duży, gdy zmieniasz rozmiar.
Pełnomocnik nie jest potrzebny do działania widoku przewijania.
źródło
Upewnij się, że właściwość contentSize widoku przewijania jest ustawiona na prawidłowy rozmiar (tj. Wystarczająco duży, aby objąć całą zawartość).
źródło
Odznaczenie „Użyj automatycznego układu” załatwiło mi sprawę.
Środowisko: xCode 5.0.2 Storyboards ios7
źródło
W moim przypadku musiałem ustawić
delaysContentTouches
na true, ponieważ wszystkie obiekty wewnątrz scrollView przechwytywały zdarzenia dotyku i obsługiwały siebie, zamiast pozwolić, aby sam scrollView obsługiwał to.źródło
Ustaw
contentSize
właściwośćUIScrollview
inViewDidLayoutSubviews
method. Coś takiegooverride func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() scrollView.contentSize = CGSizeMake(view.frame.size.width, view.frame.size.height) }
źródło
Pomysł, dlaczego widok przewijania nie przewija się, ponieważ ustawiono rozmiar zawartości do przewijania mniejszy niż rozmiar widoku przewijania, co jest błędne. Aby poruszać się po nim podczas przewijania, należy ustawić rozmiar zawartości większy niż rozmiar widoku przewijania.
Ten sam pomysł z powiększaniem, ustawiasz minimalną i maksymalną wartość powiększania, która zostanie zastosowana przez akcję powiększania.
Witamy :)
źródło
Jeden mały dodatek, wszystkie powyższe to rzeczywiste powody, dla których widok przewijania może nie być przewijany, ale czasami bezmyślnie może to być powód szczególnie, gdy widok przewijania jest dodawany za pomocą kodu, a nie IB, być może dodałeś swoje podziały do widoku nadrzędnego, a nie scrollview powoduje, że podwidok nie przewija się
i utrzymuj rozmiar zawartości ustawiony i większy niż nadrzędna ramka widoku (duhh !!)
źródło
Udało mi się to za pierwszym razem. Z automatycznym układem i wszystkim, bez dodatkowego kodu. Następnie widok kolekcji stał się bananem, awaria w czasie wykonywania, nie mogłem znaleźć przyczyny, więc usunąłem go i odtworzyłem (używam Xcode 10 Beta 4. Czułem się jak błąd), a potem przewijanie zniknęło. Jednak widok kolekcji znów zadziałał!
Wiele godzin później ... właśnie to naprawiło. Miałem następujący układ:
UIView
Wszystko jest w ograniczeniach. Obszar bezpieczny jest definiowany automatycznie przez system. W najgorszym przypadku usuń wszystkie ograniczenia dotyczące przewijania i widoków treści i nie pozwól, aby IB resetował / tworzył je za Ciebie. Wykonaj je ręcznie, to działa.
zasadniczo chodzi o to, aby widok zawartości pasował do widoku Scrollview, który pasuje do bezpiecznego obszaru.
Ale jako takie nie zadziałało. W widoku zawartości brakuje wysokości. Próbowałem wszystkiego, co mogłem, a jedyną rzeczą, która robiła sztuczkę, był widok zawartości, który utworzył widok zawartości, przeciągając kontrolkę do siebie . To zdefiniowało stałą wysokość, której wartość została obliczona z Rozmiar kontrolera widoku (zdefiniowanego jako dowolny, dłuższy niż rzeczywisty wyświetlacz, zawierającego wszystkie moje podglądy) i wreszcie zadziałało!
źródło
Jeśli otrzymujesz komunikat (IOS8 / swift),
viewDidLayoutSubviews
który nie istnieje, użyj zamiast tego poniższegooverride func viewDidAppear(animated: Bool)
To naprawiło to dla mnie
źródło
Coś, o czym wcześniej nie wspomniano!
Upewnij się, że gniazdko zostało prawidłowo podłączone do scrollView! Powinien mieć wypełnione kółko, ale nawet jeśli masz wypełnione kółko, scrollView może nie być podłączony - więc sprawdź dokładnie! Najedź na kółko i zobacz, czy podświetlony zostanie rzeczywisty widok przewijania! (To był przypadek dla mnie)
//Connect below well to the scrollView in the storyBoard @property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
źródło
W większości przypadków kod jest poprawny, jeśli korzystałeś z samouczka, ale wielu początkujących nie wie, że scrollView NIE będzie normalnie przewijał symulatora. Przewijanie ma być wykonywane tylko wtedy, gdy naciskasz podkładkę pod mysz i jednocześnie przewijasz. Wielu doświadczonych użytkowników XCode / Swift / Obj-C jest do tego przyzwyczajonych, więc nie wiedzą, jak może to zostać przeoczone przez początkujących. Cześć :-)
@IBOutlet weak var scrollView: UIScrollView! override func viewDidLoad() { super.viewDidLoad() view.addSubview(scrollView) // Do any additional setup after the view } override func viewWillLayoutSubviews(){ super.viewWillLayoutSubviews() scrollView.contentSize = CGSize(width: 375, height: 800) }
Ten kod będzie działał doskonale, o ile będziesz robić to, co powiedziałem powyżej
źródło
Dodaj
UIScrollViewDelegate
i dodając następujący kod doviewDidAppear
metody naprawiło to za mnie.@interface testScrollViewController () <UIScrollViewDelegate> -(void)viewDidAppear:(BOOL)animated { self.scrollView.delegate = self; self.scrollView.scrollEnabled = YES; self.scrollView.contentSize = CGSizeMake(375, 800); }
źródło
Jeśli żadne z innych rozwiązań nie działa dla Ciebie, sprawdź dokładnie, czy Twój widok przewijania faktycznie jest
UIScrollView
w programie Interface Builder.W pewnym momencie w ciągu ostatnich kilku dni
UIScrollView
spontanicznie zmieniłem typ na aUIView
, mimo że jego klasa powiedziałaUIScrollView
inspektorowi. UżywamXcode 5.1 (5B130a)
.Możesz utworzyć nowy widok przewijania i skopiować pomiary, ustawienia i ograniczenia ze starego widoku lub możesz ręcznie zmienić widok na a
UIScrollView
wxib
pliku. Porównałem i znalazłem następujące różnice:Oryginał:
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" directionalLockEnabled="YES" bounces="NO" pagingEnabled="YES" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Wsk-WB-LMH"> ... </scrollView>
Po spontanicznej zmianie typu:
<view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" customClass="UIScrollView" id="qRn-TP-cXd"> ... </view>
Więc wymieniłem
<view>
żyłkę na moją oryginalną<scrollView>
.Ja również zastąpić bliską tag w widoku
</view>
z</scrollView>
.Pamiętaj, aby zachować ten sam identyfikator, co w bieżącym widoku, w tym przypadku: id = "qRn-TP-cXd".
Musiałem również opróżnić xib z pamięci podręcznej Xcode, usuwając dane pochodne aplikacji:
Xcode->Window->Organizer->Projects
, wybierz projekt, w wierszu Dane pochodne kliknij Usuń ...Lub jeśli używasz urządzenia:
Xcode->Window->Organizer->Device
, wybierz swoje urządzenie-> Aplikacje, wybierz swoją aplikację, kliknij (-)Teraz wyczyść projekt i usuń aplikację z symulatora / urządzenia:
Xcode->Product->Clean
Simulator/device->press
i przytrzymajapp->click
(X), aby go usunąćPowinieneś wtedy być w stanie skompilować i uruchomić aplikację oraz ponownie mieć funkcję przewijania.
PS Nie musiałem ustawiać rozmiaru zawartości widoku przewijania
viewDidLayoutSubviews
ani wyłączać układu automatycznego, ale YMMV.źródło
Jeśli Twój
scrollView
jest podziałem plikucontainerView
jakiegoś typu, upewnij się, żescrollView
znajdujesz się w ramce lub w granicachcontainerView
. Miałem to,containerView.clipsToBounds = NO
co nadal pozwalało mi widzieć scrollView, ale ponieważscrollView
nie znajdował się w jego granicachcontainerView
, nie wykrywał zdarzeń dotykowych.Na przykład:
containerView.frame = CGRectMake(0, 0, 200, 200); scrollView.frame = CGRectMake(0, 200, 200, 200); [containerView addSubview:scrollView]; scrollView.userInteractionEnabled = YES;
Będziesz mógł zobaczyć scrollView, ale nie będzie on otrzymywać interakcji użytkownika.
źródło
dodanie poniższego kodu
viewDidLayoutSubviews
działało dla mnie z Autolayout. Po wypróbowaniu wszystkich odpowiedzi:- (void)viewDidLayoutSubviews { self.activationScrollView.contentSize = CGSizeMake(IPHONE_SCREEN_WIDTH, 620); } //set the height of content size as required
źródło
Mój problem został rozwiązany przez:
Po usunięciu górnych i / lub dolnych ograniczeń związanych z bezpiecznym obszarem i / lub nadzorem, widoki wewnątrz scrollView mogły znowu się przewijać i nie były ustalone na górze i na dole ekranu!
Mam nadzieję, że to powstrzyma kogoś przed wielogodzinnym bólem związanym z tym konkretnym problemem.
źródło
kolejny zabawny przypadek:
scrollview.superview.userInteractionEnabled musi mieć wartość true
Zmarnowałem 2 + godziny, goniąc to tylko po to, aby dowiedzieć się, że rodzicem jest UIImageView, który oczywiście ma userInteractionEnabled == false
źródło
Po nieudanych odpowiedziach udzielonych w tym wątku natknąłem się na ten artykuł z rozwiązaniem.
Istnieją dwie rzeczy, które nie są intuicyjne w konfigurowaniu widoku przewijania z automatycznym układem:
To jest istota tego artykułu. Aby uzyskać pełne wyjaśnienie, w tym ilustracje, sprawdź to.
źródło
Okazało się, że z tego autoLayout numerze ... gdybym tylko dokonać
ViewController
wykorzystaniaUIView
zamiastUIScrollView
do klasy ... a potem po prostu dodaćUIScrollView
sobie ... że to działa.źródło
Miałem ten sam problem w IB.
Po ustawieniu wiodącego, końcowego, górnego i dolnego widoku scrollView na jego superView. Wprowadziłem następujące zmiany, aby umożliwić przewijanie widoku containerView, co zadziałało.
Aby scrollView przewijał się tylko w kierunku poziomym, utwórz ograniczenie za pomocą środka scrollView Y = ContainerView centerY
i aby umożliwić przewijanie w pionie, należy ustawić centerX w scrollView = CenterX w ContainerView
źródło