Nie chcę animacji w początkowych aktualizacjach, czy na końcu bloku aktualizacji dla uitableview?

89

Mam UITableView, który używa niestandardowej komórki tabeli, a każda komórka ma UIWebView.

Ponieważ ładowanie UIWebView trwało długo, chcę uniknąć ponownego ładowania ich za wszelką cenę. W niektórych sytuacjach mam załadowane wszystkie komórki, ale ich wysokości są pomieszane. Dlatego muszę „przekazywać” tabelę bez wyzwalania funkcji „cellForRow”.

  1. Zdecydowanie nie mogę użyć reloadData ... ponieważ ponownie załaduje komórki.
  2. Próbowałem tableView.setNeedDisplay, setNeedsLayout itp., Żaden z nich nie jest w stanie zmienić kolejności komórek tabeli
  3. Jedynym sposobem, w jaki to zadziałało, jest wywołanie bloku beginupdates / endupdates, ten blok jest w stanie przekazać moją tabelę bez odpalania cellForRow! ALE nie chciałem animacji! Ten blok daje efekt animacji, ale nie chcę tego ...

Jak mogę rozwiązać mój problem?

mkto
źródło

Odpowiedzi:

216
[UIView setAnimationsEnabled:NO];
[tableView beginUpdates];
[tableView endUpdates];
[UIView setAnimationsEnabled:YES];
Evgeny Shurakov
źródło
1
To jest świetne! Uważam, że ma kilka najciekawszych zastosowań. Odkryłem, że metoda przeładowania sekcji będzie zawsze animowana, nawet jeśli przejdziesz UITableViewRowAnimationNone, ale dzięki tej animacji można łatwo ominąć!
Flying_Banana
65

Jeszcze jeden sposób na zrobienie tego za pomocą bloków

Obj-C

[UIView performWithoutAnimation:^{
   [self.tableView beginUpdates];
   [self.tableView endUpdates];
}];

Szybki

UIView.performWithoutAnimation {
    tableView.beginUpdates()
    tableView.endUpdates()   
}
Dmitriy
źródło
4

pracuję nad moim projektem, ale nie jest to powszechne rozwiązanie.

let loc = tableView.contentOffset
UIView.performWithoutAnimation {

    tableView.reloadData()

    tableView.layoutIfNeeded()
    tableView.beginUpdates()
    tableView.endUpdates()

    tableView.layer.removeAllAnimations()
}
tableView.setContentOffset(loc, animated: true)//animation true may perform better
hstdt
źródło
3

Swifties musiałem wykonać następujące czynności, aby to zadziałało:

// Sadly, this is not as simple as calling:
//      UIView.setAnimationsEnabled(false)
//      self.tableView.beginUpdates()
//      self.tableView.endUpdates()
//      UIView.setAnimationsEnabled(true)

// We need to disable the animations.
UIView.setAnimationsEnabled(false)
CATransaction.begin()

// And we also need to set the completion block,
CATransaction.setCompletionBlock { () -> Void in
    // of the animation.
    UIView.setAnimationsEnabled(true)
}

// Call the stuff we need to.
self.tableView.beginUpdates()
self.tableView.endUpdates()

// Commit the animation.
CATransaction.commit()
Neil Japhtha
źródło
Pomogło mi. Dzięki. Ważne, aby umieścić setAnimationsEnabled(true)w bloku uzupełniającym.
Lasse Bunk
Ale to nie aktualizuje stopki, dopóki nie przewiniesz widoku tabeli.
Jaś Fasola
@ Panie Fasola, jaki jest pełny przypadek? (tj. czy twój widok tabeli zawsze ma stopkę, czy próbujesz ją wstawić czy usunąć?)
Neil Japhtha
Zawsze miej stopkę, wystarczy zaktualizować stopkę (tj. W stopce są 2 widoki, trzeba ukryć / odkryć widoki w zależności od stanu).
Jaś Fasola
@ Mr.Bean co zawiera twój blok aktualizacji? Najbardziej rozszerzalną metodą byłoby ponowne załadowanie sekcji.
Neil Japhtha
1

Wolę mieć płynne przejście:

CGPoint offset = self.tableView.contentOffset;
[UIView transitionWithView:self.tableView duration:0.5 options:UIViewAnimationOptionTransitionCrossDissolve animations:^{
        [self.tableView reloadData];
        self.tableView.contentOffset = offset;
    } completion:nil];

Spróbuj.

Jorge Arimany
źródło
0

Chciałem zaktualizować wysokość komórki dla sekcji 5 i działał dla mnie następujący kod:

UiView.setAnimationsEnabled(False)
self.productTableView.reloadSections(NSIndexSet(index: SectionType.ProductDescription.hashValue), withRowAnimation: UITableViewRowAnimation.None)
self.productTableView.scrollToRowAtIndexPath(NSIndexPath(forRow: 0, inSection: 5), atScrollPosition: UITableViewScrollPosition.Bottom, animated: false)
UIView.setAnimationsEnabled(true)
Aadi007
źródło