IOS7: przesunięcie UIScrollView w UINavigationController

126

Obecnie migruję moją aplikację na iOS 7 i godzinami utknąłem na nowym zarządzaniu kontrolerem nawigacji / paskiem.

Wcześniej, kiedy mieliśmy kontroler nawigacyjny, mieliśmy taki fragment:

UINavigationController *navController = [[UINavigationController alloc]initWithRootViewController:[[MainViewController alloc]init]];

W narzędziu do tworzenia interfejsu mieliśmy możliwość ustawienia istniejącego paska nawigacji dla widoku i wszystko pasowało do zawartości rzeczywistego widoku.

OK, więc teraz nie mam pojęcia, jak prawidłowo projektować za pomocą konstruktora interfejsu. Nadal mam swój fragment do zainicjowania kontrolera navcontrollera. Jednak w konstruktorze interfejsu dla mojego MainViewController, jeśli ustawię pasek stanu na półprzezroczysty lub nieprzezroczysty pasek nawigacji, mam przesunięcie 44px na górze (patrz poniżej).


Interface Builder_________________________ I wynik


Teraz, jeśli ustawię pasek stanu na brak, nie ma przesunięcia na górze, ale ponieważ widok na symulatorze jest mniejszy z powodu paska nawigacji, dolna część widoku w konstruktorze interfejsu jest obcięta.

Interface Builder_________________________ I wynik

Wydaje mi się, że naprawdę czegoś mi brakuje, ale nie mogę znaleźć żadnego tematu ani informacji o Apple w Przewodniku przejścia na iOS7 na ten temat.

Dzięki za pomoc


EDYTOWAĆ

Jak widać na zdjęciach, pierwszym dzieckiem widoku jest UIScrollView, który zawiera obie etykiety, problem nie pojawia się, gdy nie ma scrollviewu. Pojawia się również, jeśli jest to UITableView. Jeśli etykieta znajduje się poza UIScrollView, nie ma przesunięcia do tej etykiety.

streem
źródło
Jeśli nie, możesz skorzystać z Autolayout, aby upewnić się, że niektóre widoki są w określonej odległości od góry / dołu / boku ekranu
erdekhayser
Rzeczywiście nie używam Autolayout, ale używanie go (zaznaczenie pola wyboru) nie rozwiązuje problemu.
streem
W przypadku automatycznego układania należy ustawić ograniczenia, aby widoki pozostały na miejscu. Xcode nie wie automatycznie, czego chcesz.
erdekhayser
Widząc Twoją poprzednią zmianę, właśnie odkryłem Twój problem. Niestety nie jest to najbardziej oczywiste rozwiązanie. Zamiast próbować to wszystko jeszcze raz wyjaśnić, użyłem tego filmu na Youtube, aby dowiedzieć się, jak skonfigurować widoki przewijania. youtube.com/watch?v=PgeNPRBrB18&feature=youtu.be Powodzenia. Kilka razy zajęło mi obejrzenie go, aby w pełni zrozumieć, co robi.
erdekhayser

Odpowiedzi:

286

OK, więc znalazłem rozwiązanie, ustawiłem w kontrolerze właściwość:

self.automaticallyAdjustsScrollViewInsets = false

Jednak tak naprawdę nie rozumiem prawdziwej korzyści z tej właściwości (lub dlaczego wartość domyślna jest prawdziwa)

Jedyna dokumentacja, jaką znalazłem, była tam:

Aktualizacja

W iOS 11 automaticallyAdjustsScrollViewInsetsjest przestarzałe

Powinieneś teraz użyć:

self.tableView.contentInsetAdjustmentBehavior = .never

Zachęcam również do sprawdzenia tego pytania i odpowiedzi, aby lepiej poznać te właściwości

streem
źródło
12
Świetne znalezisko. UIScrollView w scenorysie jest naprawdę skomplikowany. Chciałbym, żeby Apple sprawiło, że będzie to trochę bezproblemowe w przyszłych wersjach Xcode.
p0lAris
4
Ten kod zapobiega UIScrollViewprzewijaniu. Ale bez tego nie mogę pozbyć się przesunięcia. Weired ...
scaryguy
9
Tę flagę można również wyłączyć w scenorysie / końcówce, kontroler widoku ma pole wyboru „Dostosuj wstawki widoku przewijania”. Od tak dawna walę głową w ścianę, próbując rozwiązać swoje problemy z widokami przewijania i automatycznym układem, jeszcze bardziej skomplikowane przez obsługę iOS 6 i 7. Wielkie dzięki za to, że w końcu zapewniłem rozwiązanie!
Newtz
2
Dokument aplikacji powiedziałby, że ustawienie navigationbar.translucent = YES zapobiegnie wypychaniu zawartości przez pasek nawigacji. To największe kłamstwo i kosztowało mnie wiele godzin pracy do tego postu. Ponadto należy ustawić self.automaticallyAdjustsScrollViewInsets = NO; Bardzo dziękuję za ten post !!!!!!! Jabłko i jabłko?
user779764
Okazało się, że spowodowało to przesunięcie granic mojego UIScrollView w dół o wysokość paska nawigacyjnego (-64 punkty). Ręcznie zastąpiłem to na 0, ale stwierdziłem, że UISrollView nadal przewijałby się po osi Y i „przyciągał” do wyimaginowanej linii na -64. Twoje rozwiązanie rozwiązało ten problem.
gdbj
92

@ Odpowiedź Justafingera również działała na mnie jak urok.

Chciałem tylko dodać, że to ustawienie można również łatwo dostosować z poziomu kreatora interfejsu.

  1. Wybierz kontroler widoku
  2. Kliknij kartę „Inspektor atrybutów”
  3. Odznacz „Dostosuj przewijanie wstawek widoku”
  4. Cieszyć się!

wprowadź opis obrazu tutaj

Myxtic
źródło
Spędziłem wieki szukając tej opcji we właściwościach UIScrollView, a nie kontrolera widoku! Dzięki!
Dominic Williams,
11

Miałem ten sam problem, ale znalazłem dość dziwną właściwość w ViewController w konstruktorze interfejsu, która wydaje się być przyczyną tego problemu. Istnieje zestaw pól wyboru „Rozszerz krawędzie”. Usunąłem zaznaczenie „Pod górnymi pasami” i wszystko zaczęło się układać prawidłowo.

Ben Nicholas
źródło
Tak, ten działał dla mnie lepiej niż „Dostosuj przewijane wstawki widoku”
Dmytro
2

Z automaticAdjustsScrollViewInsets ustawionym na YES (ustawienie domyślne) występuje niezgodność w pozycjonowaniu widoku scrollview między ios6 i ios7, więc aby były spójne, musisz wyłączyć to ustawienie. Jednak ios6 ulegnie awarii, jeśli pojawi się automatycznie AdjustsScrollViewInsets, więc musisz albo dokonać programowej zmiany w opcji automaticAdjustsScrollViewInsets w zależności od ios7, albo wyłączyć tę opcję za pomocą storyboardu / NIB

dawid
źródło
2

Miałem podobny problem, po odrzuceniu viewController, contentOffset z mojego tableView został zmieniony na (0, -64).

moje rozwiązanie było trochę dziwne, wypróbowałem wszystkie inne odpowiedzi, ale nie powiodło się, jedyną rzeczą, która rozwiązała mój problem, była zmiana pozycji tableView w drzewie kontrolek .xib

była to pierwsza kontrolka w widoku nadrzędnym w następujący sposób:

przed

Przeniosłem tableView zaraz po ImageView i zadziałało:

po

wydaje się, że ustawienie widoku tabeli na pierwszej pozycji powodowało problem, a przeniesienie widoku tabeli na inną pozycję rozwiązało problem.

PD Nie używam autoLayout ani scenorysów

mam nadzieję, że to może komuś pomóc!

Chuy47
źródło
Zauważyłem to dziwne zachowanie, myślę, że logika jest taka, że ​​scrollViewInsets są automatycznie dostosowywane, gdy scrollview jest pierwszym dzieckiem. W przeciwnym razie nie ma to sensu, ponieważ widok przewijania prawdopodobnie nie jest pełny ekran.
streem
1

Ja też mam ten problem.

UIScrollView rozmiar zawartości jest obliczany przez system operacyjny jako inne rozmiary, pochodzenie dostarczane przez system ograniczeń - dlatego system operacyjny ma wątpliwości.

Rozwiązanie problemu - należy wyraźnie określić rozmiar zawartości UIScrollView:

  1. Osadź zawartość przewijalną na UIView(zmieniam jej nazwę na ContentView)
  2. Dodaj ograniczenia:

ContentView.Weight = View.Weight i ContentView.Height = View.Height

wprowadź opis obrazu tutaj

maslovsa
źródło
0

Wygląda na to, że rozwiązaniem obejścia problemu jest wyświetlenie pliku storyboardu jako „iOS 6.1 i starsze” (wybierz plik storyboardu-> Inspektor plików-> Dokument kreatora interfejsu-> Wyświetl jako. Pozycjonowanie podglądów podrzędnych w tym trybie pokazuje przesunięcie.

swhitman
źródło
Cóż, nie używam scenorysu. Jednak nie jestem pewien, czy jest to problem z ios6 do ios7, powyższy przykład został w całości utworzony z iOS 7. Ponadto redagowałem moje pytanie, pojawia się (o ile wiem) tylko z uiscrollview i uitableview.
streem
Hmm interesujące ... Patrząc na to, możesz dodać variant = "6xAndEarlier" na górę XIB w elemencie dokumentu, ponieważ jest to różnica podczas odwracania bitu, o którym wspomniałem powyżej. I do Twojej wiadomości, ten problem występuje również w przypadku uiwebview.
swhitman
0

Dziękuję wam za rozwiązania! Zmagałem się godzinami, próbując rozwiązać problem. Wszystko było w porządku, gdy nie było zaangażowanego paska nawigacyjnego, ale poszło źle w momencie, gdy osadziłem ViewController w NavigationController.

Rozwiązałem to, usuwając zaznaczenie opcji Dopasuj wstawki widoku przewijania i Pod górnymi paskami . Oba znajdują się w inspektorze atrybutów ViewController. Stukrotne dzięki!

Jackson Gan
źródło