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
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
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.
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.
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
);
}
contentSize
na rozmiar contentView
, rozmiar scrollView i contentView wydaje się być ustawiony jako taki sam. Ale ustawienie wysokości na contentSize
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:
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.
Upewnij się, że właściwość contentSize widoku przewijania jest ustawiona na prawidłowy rozmiar (tj. Wystarczająco duży, aby objąć całą zawartość).
Odznaczenie „Użyj automatycznego układu” załatwiło mi sprawę.
Środowisko: xCode 5.0.2 Storyboards ios7
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.
Ustaw contentSize
właściwość UIScrollview
in ViewDidLayoutSubviews
method. Coś takiego
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.contentSize = CGSizeMake(view.frame.size.width, view.frame.size.height)
}
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 :)
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 !!)
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!
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;
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
Dodaj UIScrollViewDelegate
i dodając następujący kod do viewDidAppear
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);
}
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 a UIView
, mimo że jego klasa powiedziała UIScrollView
inspektorowi. Używam Xcode 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
w xib
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 przytrzymaj app->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.
Jeśli Twój scrollView
jest podziałem plikucontainerView
jakiegoś typu, upewnij się, że scrollView
znajdujesz się w ramce lub w granicach containerView
. Miałem to, containerView.clipsToBounds = NO
co nadal pozwalało mi widzieć scrollView, ale ponieważ scrollView
nie znajdował się w jego granicach containerView
, 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.
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
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.
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
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.
Okazało się, że z tego autoLayout numerze ... gdybym tylko dokonać ViewController
wykorzystania UIView
zamiast UIScrollView
do klasy ... a potem po prostu dodać UIScrollView
sobie ... że to działa.
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