2015-06-09 13 views
7

Pozwoliłem użytkownikowi na zmianę kolejności wierszy w tableView. Ponieważ to zdarzenie wpływa na zawartość - niektóre wartości liczbowe w komórkach powinny być aktualizowane - we wszystkich pozostałych wierszach nazywam reloadData w moveRowAtIndexPath. A potem pojawiają się dziwne efekty.Jak ponownie załadować tableview po zmianie kolejności wiersza? Wiersze mają zmienną wysokość

tj. Komórki wydają się zachodzić na siebie podczas dotykania dragger, a niektóre komórki zaczynają poruszać się w górę iw dół. Ważne jest, aby wiedzieć, że wysokość komórek jest różna.

Dziwne, że jeśli usuniemy reloadData z moveRowAtIndexPath, wszystkie te zjawiska znikną. Tylko treść jest nieprawidłowa.

Jak zatem ponownie załadować dane po zmianie kolejności?


UPDATE: Co mam zrobić komórek międzyczasie rekonfiguracji w viewDidLayoutSubviews zamiast rozmowy reloadData Koniec moveRowAtIndexPath. Działa to w 90%, jak się spodziewam, ale wciąż wiersze są czasami nieco wyższe, niż powinny.

override func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) { 

    //.. 

    reorderOccured = true 
} 

override func viewDidLayoutSubviews() { 

    if reorderOccured { 

     for cell in tableView.visibleCells() as! [UITableViewCell] { 

      let ip = tableView.indexPathForCell(cell) 
      if ip != nil { 
       self.configureCell(cell, indexPath: ip!) 
      } 
     } 

     reorderOccured = false 
    } 
} 
+0

może Cię to zainteresować: http://stackoverflow.com/questions/30758111/an-extra-view-appears-in-cell-when-pressing-reorder-dragger-why –

Odpowiedz

3

znalazłem tutaj odpowiedzi: https://stackoverflow.com/a/4692563/239219

[tableView beginUpdates]; 
[tableView endUpdates]; 

Zmusza kod UITableView aby przeładować tylko rozmiary komórek, ale nie komórka zawartość.

+0

To było również wspomniane w tym roku WWDC podczas Cocoa Touch Best Practices http://asciiwwdc.com/2015/sessions/231?q=cocoa%20touch%20best%20practices –

2

Po zmianie kolejności nie należy dzwonić pod numer reloadData. Musisz wprowadzić te same zmiany w danych, co zmiany wprowadzone na ekranie. Na przykład: jeśli komórkę nr 2 przestawiłeś na pozycję 6, musisz usunąć obiekt, który wypełni komórkę nr.2 i wstawić ją ponownie na pozycję 6. Nie podano wystarczającej ilości szczegółów, ale zazwyczaj zachowałbyś swoje dane w tablicy obiektów. Ta tablica musisz dokonać zmian, więc twoje źródło danych jest prawidłowe.

Oto szczegóły dotyczące firmy Apple w zakresie: link.

Po prostu przeczytałem zaktualizowaną wersję po wysłaniu odpowiedzi. Wygląda na to, że naprawdę potrzebujesz reloadData. W takim przypadku radzę załadować ponownie po małym opóźnieniu z blokiem dispatch_async w głównym wątku. Powiedz po 0.1.

+0

, jeśli czytasz UPDATE- ed części, nie nazywam już 'reloadData' już, ale wywołaję' reconfigureCell' dla każdej komórki, w 'viewDidLayoutSubviews', ale nadal czasami zachodzę na siebie zjawisko –

+0

czy korzystasz ponownie z tej samej komórki dla innej wysokości?to jest powód –

+0

odnoszące się do artykułu, który łączyłeś, jeśli wiersze mają taką samą wysokość niż ** nakładające się zjawisko nie powstaje ** –

0

Nie mogę jeszcze skomentować odpowiedzi pteofil, ale on ma rację: jeśli masz numerowany zestaw wierszy w tabeli i przenosisz jedno wywołanie moveRow (...), twoja animacja do przeniesienia będzie anulowane przez tableView.reloadData().

Jako takie opóźniłem przeładowanie danych (które zmienia numerację wszystkich widocznych komórek na podstawie zaktualizowanego źródła danych (nie zapomnij tego zrobić, gdy przenosisz rzeczy!)) Kilkaset milisekund i działa teraz idealnie i również wygląda świetnie.

Powiązane problemy