Não quero animação no início das atualizações, fim do bloco de atualizações para uitableview?

89

Eu tenho um UITableView que está usando uma célula de tabela personalizada e cada célula tem um UIWebView.

Como o UIWebView demorou muito para carregar, quero evitar recarregá-los a todo custo. Em algumas situações, tenho todas as células carregadas, mas suas alturas estão desordenadas. Portanto, preciso "retransmitir" a tabela sem acionar a função "cellForRow".

  1. Definitivamente, não posso usar reloadData ... porque ele recarregará as células novamente.
  2. Tentei tableView.setNeedDisplay, setNeedsLayout etc, nenhum deles é capaz de reorganizar as células da tabela
  3. A única maneira de funcionar é chamar o bloco beginupdates / endupdates, esse bloco é capaz de retransmitir minha tabela sem disparar cellForRow! MAS, eu não queria a animação! Este bloco produz um efeito de animação mas eu não quero ...

Como posso resolver meu problema?

mkto
fonte

Respostas:

217
[UIView setAnimationsEnabled:NO];
[tableView beginUpdates];
[tableView endUpdates];
[UIView setAnimationsEnabled:YES];
Evgeny Shurakov
fonte
1
Isso é ótimo! Acho que tem algumas aplicações muito interessantes. Descobri que o método de recarregar seções sempre animará mesmo se você passar UITableViewRowAnimationNone, mas com isso a animação pode ser facilmente contornada!
Flying_Banana
65

Mais uma maneira de fazer isso usando blocos

Obj-C

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

Rápido

UIView.performWithoutAnimation {
    tableView.beginUpdates()
    tableView.endUpdates()   
}
Dmitriy
fonte
4

trabalhando no meu projeto, mas não uma solução comum.

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
fonte
3

Swifties eu tive que fazer o seguinte para que isso funcionasse:

// 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
fonte
Me ajudou. Obrigado. Importante para colocar setAnimationsEnabled(true)dentro do bloco de conclusão.
Lasse Beliche
Mas isso não atualiza o rodapé até que você role a visualização da tabela.
Sr. Bean
@ Mr.Bean qual é o caso completo? (ou seja, seu tableview sempre tem um rodapé, você está tentando inserir ou remover um?)
Neil Japhtha
Sempre tenha um rodapé, só precisa atualizar o rodapé (ou seja, há 2 visualizações dentro do rodapé, é necessário ocultar / reexibir as visualizações dependendo da condição.)
Mr. Bean
@ Mr.Bean o que seu bloco de atualização contém? O método mais extensível aqui seria recarregar a seção.
Neil Japhtha
1

Eu prefiro ter uma transição suave:

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

De uma chance.

Jorge Arimany
fonte
0

Eu queria atualizar a altura da célula para a seção 5 e o código a seguir funcionou para mim:

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
fonte