2013-07-12 15 views
9

Mój UITableView ma kilka komórek wielokrotnego użytku, a po dotknięciu jednego z nich, przenosi mnie do innego kontrolera widoku (poprzez push pushue) pokazując szczegóły tej komórki (powiedzmy jest to przedmiot, więc pokazuje szczegóły dotyczące przedmiotu - nazwy, ceny, zdjęcia itp.). Po uruchomieniu tego kontrolera widoku (poprzez naciśnięcie przycisku wstecz), UITableView ma dziwne zachowanie:UITableViewController dziwne zachowanie po pojawieniu kontrolera widoku

a) jeśli jest przewinięty do samego końca, przewinie się automatycznie w górę (około 50 punktów), pozostawiając ostatnią komórkę ledwo widoczną, więc muszę ponownie przewinąć w dół. Moja komórka ma 60 punktów wzrostu.

b) pasek przewijania zawsze pokazuje się, a następnie znika, wskazując, że coś się porusza, że ​​UITableView (chociaż jeśli nie przewinie się do dołu, zawartość nie będzie się poruszać automatycznie).

Zdarza się to w wielu numerach UITableView, które mam w mojej aplikacji. Nie zmuszam do ponownego załadowania widoku tabeli w viewWillAppear, więc nie rozumiem, co się dzieje. Moja zawartość jest statyczna po załadowaniu z serwera (chyba że użytkownik ją zmieni, a następnie zostanie wykonane ponowne ładowanie). Ale po prostu pokazywanie szczegółów przedmiotu i wstawianie tego VC niczego nie zmienia w widoku tabeli.

Edycja: Okej, doszedłem do tego, o co chodzi: ukrywam UIToolbar, kiedy pcham ten segue. Jeśli utrzymam ją zawsze widoczną (której nie chcę), to nadal pokazuje paski przewijania animujące się po pojawieniu się w widoku tabeli, ale nie przewija widoku tabeli, jeśli jest w kilku ostatnich wierszach.

Odpowiedz

2

Udało mi się naprawić pierwszy numer. Wygląda na to, że widok tabeli nie uwzględnia 44 punktów z UIToolbar.

zapisać tableview offsetowego w prepareForSegue: (zapisania jej w nieruchomości CGPoint)

self.tableViewScrollOffset = self.tableView.contentOffset; 

Następnie w viewWillAppear: należy sprawdzić, czy został on zmodyfikowany. Jeśli tak, przywróć go.

if(self.tableView.contentOffset.y != self.tableViewScrollOffset.y) { 
     [self.tableView setContentOffset:self.tableViewScrollOffset]; 
     self.tableViewScrollOffset = CGPointZero; 
    } 
+0

Czy mógłbyś wyjaśnić bardziej szczegółowo, dlaczego tak się dzieje? A może ktoś. – Krtko

+0

To niesamowite ... rozwiązało podobny problem ... Problem polega na tym, że za każdym razem, gdy nawigujesz z powrotem z kontrolera view, przesunięcie przewijania widoku stołu zmienia się odpowiednio. Tak więc musisz przechwycić wartość contentoffset w właściwości wewnątrz metody prePareForSegue: (tj. Przed nawigacją), a następnie sprawdzić, czy w tej samej klasie wewnątrz metody viewWillAppear:. A jeśli zostanie zmieniony, ustaw wartość właściwości scrolloffset na zero –

0

Po prostu przeczucie, czy masz kłamcę, którego nie wiesz, scrollToRowAtIndexPath:atScrollPosition:animated?

+0

Nie, szukałem cały mój projekt, który w Xcode i żadne linie kodu pop-up. – swiftcode

+0

Zaktualizowałem swój problem, podając kilka trafniejszych informacji. – swiftcode

7

Dodaj poniższe do viewDidLoad.

self.automaticallyAdjustsScrollViewInsets = NO; 

Rozwiązałam mój problem z widokiem tabeli w dół po przejściu z powrotem do kontrolera widoku.

3

To zachowanie jest rzeczywiście błędem w iOS 8.x.

Wszystkie dotychczasowe odpowiedzi naprawdę nie rozwiązują problemu. Problem polega na tym, że system iOS zapomina (lub nie bierze pod uwagę wcześniej obliczonych rozmiarów komórek, gdy tabela jest przerysowywana na przykład podczas wyświetlania widoku.

Jedna z metod rozwiązania tego problemu znajduje się tutaj: UITableView layout messing up on push segue and return. (iOS 8, Xcode beta 5, Swift) (więc to pytanie jest nawet duplikatem tego).

Jednak rozwiązanie pod warunkiem, że jest przesadą i istnieją pewne sytuacje, dlaczego to buforowanie zawiedzie (na przykład UIContentSizeCategoryDidChangeNotification nie jest uważany)

Ale jest dość prostsze rozwiązanie, mimo że jest nieparzysta:

Jeśli korzystasz z instrukcji performSequeWithIdentifier w didSelectRowAtIndexPath, po prostu dodaj już przed chwilą [self.tableView reloadData].

Jeśli używasz seque IB z komórki, po prostu dodaj [self.tableView reloadData] w swoim kodzie prepareForSeque.

Powodem, dla którego rozwiązuje to problem jest fakt, że zmusi to iOS do ponownego oszacowania widocznych komórek, dzięki czemu nie będzie już przewijać zawartości do innej lokalizacji. Na szczęście, tableView reloadData nie kosztuje tutaj zbyt wiele kosztów, ponieważ tylko widoczne komórki zostaną ponownie oszacowane.

0

Miałem też do czynienia z tym problemem. Udało mi się to ustalić. Przyczyną w moim przypadku jest wysokość nagłówka tableview, który polegał na obliczaniu tekstu bazowego, a wysokość tekstu była ujemna, ponieważ widok tabeli ulegał przesunięciu, mimo że wartość contentinset i scrollinset wynosi zero.

To działo się tylko po raz pierwszy. Następnym razem obliczenie jest poprawne. Jedną z rzeczy, którą odkryłem, jest to, że kiedy klasa A (posiadająca tableview) wypchnęła inną klasę B z init. Gdy klawiatura z klasy B jest otwarta, wywoływana jest viewDidLoad klasy A. i zanim klasa B zostanie wyładowana ze sterownika nawigacyjnego. Widok tabeli jest przeładowywany dla klasy A.

0

Ustawienie automatycznegoAdjustsScrollViewInsets, jak zasugerowano powyżej, nie działało, ani buforowanie i ustawianie pracy tableViewScrollOffset.

Stąd powstało obejście, które zadziałało dla mnie jak urok.

Obejście polegało na dodaniu pustego interfejsu UIView o wysokości 1 piksela i szerokości 320 pikseli i umieszczeniu go między "Przewodnikiem po topografii układu" a interfejsem UITableView. Tło tego widoku można ustawić tak, aby było jasne, aby było niewidoczne.

Teraz korzystając z funkcji Autolayouts, ustaw widok Dummy View na górze. Teraz ustaw górne ograniczenie tableview w odniesieniu do Dummy View. Odkryto, że rozwiązało to kwestię niewłaściwego rozmieszczenia tableview.

Zrzut ekranu Widok dummy wraz z ograniczeniami autolayout został udostępniony dla łatwego odniesienia. Widok Dummy został ustawiony na większą wysokość i czerwony kolor tła wyłącznie w celach ilustracyjnych.

enter image description here