Eu sinto que isso pode ser um problema comum e queria saber se havia alguma solução comum para isso.
Basicamente, meu UITableView possui alturas dinâmicas de células para cada célula. Se eu não estiver na parte superior do UITableView e eu tableView.reloadData()
, a rolagem para cima se tornará irregular.
Acredito que isso se deve ao fato de que, ao recarregar os dados, enquanto estou rolando a tela para cima, o UITableView está recalculando a altura de cada célula que fica visível. Como mitigar isso ou como recarregar os dados apenas de um determinado IndexPath até o final do UITableView?
Além disso, quando consigo rolar até o topo, posso rolar para baixo e para cima, sem problemas, sem pular. Provavelmente, porque as alturas do UITableViewCell já foram calculadas.
fonte
reloadRowsAtIndexPaths
. Mas (2) o que você quer dizer com "nervoso" e (3) você definiu uma altura estimada de linha? (Apenas tentando descobrir se há uma solução melhor que permitiria que você atualizar a tabela dinâmica.)x
até a última linha no meu TableView ... mas, como estou inserindo novas linhas, não funcionará, não sei como será o final da minha tableview antes de recarregar os dados.Respostas:
Para evitar saltar, salve as alturas das células quando elas carregam e forneça o valor exato em
tableView:estimatedHeightForRowAtIndexPath
:Rápido:
Objetivo C:
fonte
cellHeightsDictionary
:cellHeightsDictionary = [NSMutableDictionary dictionary];
estimatedHeightForRowAtIndexPath:
retorna um valor duplo pode causar um*** Assertion failure in -[UISectionRowData refreshWithSection:tableView:tableViewRowData:]
erro. Para consertar, emreturn floorf(height.floatValue);
vez disso.Versão rápida 3 da resposta aceita.
fonte
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
, isso lida com todo o cálculo de altura que eu preciso.UITableViewDelegate
à minha aula. A conformidade com esse protocolo é necessária porque contém awillDisplay
função mostrada acima . Espero poder salvar alguém da mesma luta.O salto é devido a uma altura estimada ruim. Quanto mais o estimado RowHeight diferir da altura real, mais a tabela poderá pular quando for recarregada, especialmente quanto mais abaixo ela for rolada. Isso ocorre porque o tamanho estimado da tabela difere radicalmente do tamanho real, forçando a tabela a ajustar seu tamanho e deslocamento de conteúdo. Portanto, a altura estimada não deve ser um valor aleatório, mas perto do que você pensa que a altura será. Eu também experimentei quando defino
UITableViewAutomaticDimension
se suas células são do mesmo tipo entãose você tem variedade de células em seções diferentes, acho que o melhor lugar é
fonte
tableView(_:estimatedHeightForHeaderInSection:)
Resposta @Igor está funcionando bem neste caso, o
Swift-4
código dela.nos seguintes métodos de
UITableViewDelegate
fonte
Eu tentei todas as soluções alternativas acima, mas nada funcionou.
Depois de passar horas e passar por todas as frustrações possíveis, descobri uma maneira de consertar isso. Esta solução é um salvador de vida! Trabalhou como um encanto!
Swift 4
Eu o adicionei como uma extensão, para tornar o código mais limpo e evitar escrever todas essas linhas toda vez que eu quiser recarregar.
finalmente ..
OU você pode realmente adicionar essas linhas no seu
UITableViewCell
awakeFromNib()
métodoe faz normal
reloadData()
fonte
reloadWithoutAnimation
mas onde está areload
parte?tableView.reloadData()
primeiro e depoistableView.reloadWithoutAnimation()
ainda funciona.Eu uso mais maneiras de corrigi-lo:
Para o controlador de exibição:
como a extensão para UITableView
O resultado é
fonte
Encontrei isso hoje e observei:
cellForRowAtIndexPath
não ajuda.A correção foi realmente bem simples:
Substitua
estimatedHeightForRowAtIndexPath
e verifique se ele retorna os valores corretos.Com isso, todos os estranhos tremores e pulos no UITableViews pararam.
NOTA: Eu realmente sei o tamanho das minhas células. Existem apenas dois valores possíveis. Se as células são realmente de tamanho variável, então você pode querer armazenar em cache a
cell.bounds.size.height
partir detableView:willDisplayCell:forRowAtIndexPath:
fonte
Na verdade, você pode recarregar apenas determinadas linhas usando
reloadRowsAtIndexPaths
, ex:Mas, em geral, você também pode animar as alterações na altura da célula da tabela da seguinte maneira:
fonte
Aqui está uma versão um pouco mais curta:
fonte
Substituindo o método estimadoHeightForRowAtIndexPath por um valor alto, por exemplo, 300f
Isto deve resolver o problema :)
fonte
Acredito que foi introduzido um erro no iOS11.
É quando você faz um
reload
tableViewcontentOffSet
inesperadamente alterado. De fatocontentOffset
, não deve mudar após uma recarga. Isso costuma ocorrer devido a erros de cálculo deUITableViewAutomaticDimension
Você precisa salvar o seu
contentOffSet
e redefini-lo com o valor salvo após o término da recarga.Como você usa isso?
Esta resposta foi derivada daqui
fonte
Este funcionou para mim no Swift4:
fonte
Nenhuma dessas soluções funcionou para mim. Aqui está o que eu fiz com o Swift 4 & Xcode 10.1 ...
Em viewDidLoad (), declare a altura da linha dinâmica da tabela e crie restrições corretas nas células ...
Também em viewDidLoad (), registre todas as pontas de suas células tableView na visualização de tabela como esta:
Em tableView heightForRowAt, retorne a altura igual à altura de cada célula em indexPath.row ...
Agora forneça uma altura de linha estimada para cada célula em tableView estimadoHeightForRowAt. Seja o mais preciso possível ...
Isso deve funcionar ...
Não precisei salvar e definir contentOffset ao chamar tableView.reloadData ()
fonte
Eu tenho 2 alturas de células diferentes.
Depois que adicionei o estimadoHeightForRowAt , não houve mais pulos.
fonte
Tente ligar
cell.layoutSubviews()
antes de retornar o celularfunc cellForRowAtIndexPath(_ indexPath: NSIndexPath) -> UITableViewCell?
. É conhecido bug no iOS8.fonte
Você pode usar o seguinte em
ViewDidLoad()
fonte
Eu tive esse comportamento de salto e inicialmente consegui atenuá-lo definindo a altura exata estimada do cabeçalho (porque eu tinha apenas uma possível visualização do cabeçalho), no entanto, os saltos começaram a ocorrer dentro dos cabeçalhos especificamente, não afetando mais a tabela inteira.
Seguindo as respostas aqui, eu tinha a pista de que estava relacionada a animações, então descobri que a exibição da tabela estava dentro de uma pilha e, às vezes, chamava-se
stackView.layoutIfNeeded()
dentro de um bloco de animação. Minha solução final foi garantir que essa chamada não acontecesse, a menos que "realmente" fosse necessário, porque o layout "se necessário" apresentava comportamentos visuais nesse contexto, mesmo quando "não necessário".fonte
Eu tive o mesmo problema. Eu paginei e recarreguei os dados sem animação, mas não ajudou o pergaminho a evitar pular. Eu tenho tamanhos diferentes de IPhones, o pergaminho não estava agitado no iphone8, mas estava agitado no iphone7 +
Apliquei as seguintes alterações na função viewDidLoad :
e meu problema resolvido. Espero que ajude você também.
fonte
Uma das abordagens para resolver esse problema que encontrei é
fonte
Na verdade, eu descobri se você usa
reloadRows
causando um problema de salto. Então você deve tentar usarreloadSections
assim:fonte