2016-12-08 6 views
10

Myślę, że główną przyczyną jest to, że estimatedRowHeight jest używany do przyjmowania założeń na temat podstawowej UIScrollView.contentOffset, ale to zawsze będzie błędne z definicji, ponieważ jest oszacowaniem. Rzeczywiste wysokości rzędów są całkowicie różne w zależności od zawartości komórki i orientacji urządzenia.Jak mogę naprawić lub obejść tę tabelę Wywołać błąd autolayout textField?

Nawet jeśli zaimplementuję estimatedHeightForRowAtIndexPath w celu zapewnienia dokładniejszych szacunków, usterki nadal występują.

Tak więc, gdy zaczynasz od góry i przewijasz w dół, wszystko jest w porządku, ponieważ TableView uczy się rzeczywistych wysokości komórek, zachowując synchronizację contentOffset z pozycjami komórek. Ale gdy tylko zmienisz wszystkie rzeczywiste wysokości komórek, więc UITableView jest obecnie niezsynchronizowany, nie wie, dokąd przejść.

Ale są jeszcze dziwniejsze rzeczy dzieją się też czasami komórka UITextField skończy się na szczycie innej komórki, i pozostają tam zatrzymany ...

Zresztą ja gotuje to wszystko na prostym przykładzie.

https://github.com/trapper-/autolayout-glitch

  • test z iPhone, a jeśli za pomocą symulatora następnie włączyć klawiaturę ekranową.
  • Zobaczysz wiele wizualnych usterki po prostu bawiąc się przewijając, wybierając pola i obracając.
  • Dla prostego powtarzalnego przykładu.
  • Przewiń w dół.
  • Wybierz jedną z ostatnich kilku UITextField's, aby UITableView trzeba było przewinąć, aby upewnić się, że pole będzie widoczne.
  • Obróć urządzenie.
+0

Chociaż nie jest idealny, ale wywołanie reloadData w instancji tableView powinno pomóc. Spróbowałeś? –

+0

Autolayout nie działa dobrze z UITableView. Rozważ skorzystanie z CollectionView. To jest świetny post na temat granic UITableView: https://pspdfkit.com/blog/2017/the-case-for-deprecating-uitableview/ –

+0

Czy mówisz, że 'UICollectionView' nie ma tych samych rodzajów usterki? Jeśli tak, byłoby to świetne rozwiązanie. – trapper

Odpowiedz

1

Zabawiam się twoim kodem przez kilka minut, ponieważ borykałem się z podobnymi problemami. Miałem nadzieję, że będę mógł pomóc, ale nie udało mi się go w pełni naprawić.

Co mogę zaoferować to, że zrobiłem jakiś postęp w.

Gdy urządzenie obraca się, należy zaimplementować metody UIViewcontroller, które mówią, że tak się stanie i tak się stało. Kiedy to nastąpi, buforuj widoczne wiersze. Następnie po załadowaniu tabeli ponownie przewiń do widocznych wierszy.

Wygląda to tak:

- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration 
{ 
    // Save the visible row position 
    self.visibleRows = [self.tableView indexPathsForVisibleRows]; 
} 

-(void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation 
{ 
    [self.tableView reloadData]; 
    // Scroll to the saved position prior to screen rotate 
    [self.tableView scrollToRowAtIndexPath:[self.visibleRows objectAtIndex:0] atScrollPosition:UITableViewScrollPositionBottom animated:NO]; 
} 

visibleRows jest @property tablica na ViewController.

Pozwoliło to przejść do rightish miejscu (podejrzewam, że jeśli faktycznie przechowywane poza pojedynczą komórkę, że użytkownik manipuluje, to będzie Ci 100% do właściwej komórki za każdym razem.

Co to zrobił nie, czy to, że ciągle jeszcze tańczono UITextFields niepoprawnie (czasami) z kilkoma obrotami urządzeń

To znowu nie jest rozwiązanie - ale chciałem podzielić się tym, co zobaczyłem, więc mam nadzieję, że pomoże to znaleźć rozwiązanie .

Powodzenia!

+0

Niezły pomysł dotyczący widocznego śledzenia wierszy, ale mam też wiele problemów z metodą scrollToRowAtIndexPath. Nie wie, gdzie przewijać. tzn. nie poprawnie tłumaczyć indexPath na odpowiedni contentOffset. – trapper

+0

Tak, podejrzewam, że ma to związek z faktem, że komórki zaczynają układać wszystko, co jest squirrely. –

0

jestem dość pewny twój problem jest z linią:

self.tableView.estimatedRowHeight = 44; 

Wynika to w tableview jakiejś optymalizacji wokół tego szacunkowej wysokości. Nie mogłem się domyślić, dlaczego to się załamuje, gdy wybrano pole tekstowe, ale właśnie to udało mi się zawęzić. Jeśli faktycznie obliczyć wysokość dla każdego wiersza jawnie problem wydaje się odejść (zauważ, że to jest tylko przybliżonym przykładem, i trzeba by umieścić trochę więcej myśli w faktycznej realizacji):

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 

    if (indexPath.row % 2) { 

     return 44.f; 

    } else { 

     NSString *text = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; 

     CGRect frame = [text boundingRectWithSize:CGSizeMake(350.f, CGFLOAT_MAX) 
              options:NSStringDrawingUsesLineFragmentOrigin 
             attributes:@{ NSFontAttributeName:[UIFont systemFontOfSize:14.f] } 
              context:nil]; 

     return frame.size.height; 
    } 
} 
0

Przyjrzałem się temu projektowi. Moją najlepszą propozycją złagodzenia niektórych problemów było poprawienie obliczenia wysokości szacunkowej. Jeśli komórki widoku tekstu będą większe, szacowana wysokość musi być bliższa średniej wysokości komórki, więc przy obrocie mniejszą zmianę rozmiaru.

- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath (NSIndexPath *)indexPath 
{ 
    if (indexPath.row % 2) { 
     return 44.0f; 
    } else { 
     return 175.0f; 
    } 
} 

Teraz jak na dziwne problemu z UITextField, myślę, że może trzeba rozważyć, że komórki te są ponownie wykorzystywane nawet w rotacji, więc jeśli UITextField jest nadal pierwszy responder mimo że komórka została ponownie wykorzystane, to wtedy klawiatura ma problemy z śledzeniem pola tekstowego.

Można zobaczyć ten wynik tylko przez ustawienie znacznika na komórce i obserwować jak to losowo zmienia kolejność na obrót tak:

NSString* cellID = @"TextFieldCell"; 
TextFieldCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID forIndexPath:indexPath]; 
NSLog(@"cell %@, changing to %@", @(cell.tag), @(indexPath.row)); 
cell.tag = indexPath.row; 
return cell; 

Moja propozycja na to albo 1) nie używać pól tekstowych komórki widoku tabeli lub 2) wymyślić nowy sposób, aby umożliwić użytkownikowi wprowadzanie tekstu podczas przewijania elementów. Na przykład, umieść kopię pola tekstowego w widoku nad widokiem tabeli i zarządzaj nią ręcznie podczas wprowadzania tekstu, a następnie skopiuj tekst z powrotem do komórki, gdy tekst zostanie ukończony. 3) Opcja 3 polega na sprawdzeniu, czy biblioteka menedżerów klawiatury może pomóc. Bardzo lubię używać IQKeyboardManager. Jest to naprawdę przydatne rozwiązanie do zarządzania klawiaturą.

Powiązane problemy