J'ai l'impression que cela pourrait être un problème courant et je me demandais s'il y avait une solution commune à ce problème.
Fondamentalement, mon UITableView a des hauteurs de cellule dynamiques pour chaque cellule. Si je ne suis pas en haut de UITableView et moi tableView.reloadData()
, le défilement vers le haut devient instable.
Je pense que cela est dû au fait que, parce que j'ai rechargé des données, au fur et à mesure que je défile vers le haut, l'UITableView recalcule la hauteur de chaque cellule qui devient visible. Comment puis-je atténuer cela ou comment recharger uniquement les données d'un certain IndexPath à la fin de UITableView?
De plus, lorsque je parviens à faire défiler tout le chemin vers le haut, je peux faire défiler vers le bas puis vers le haut, sans problème sans sauter. Cela est probablement dû au fait que les hauteurs UITableViewCell ont déjà été calculées.
la source
reloadRowsAtIndexPaths
. Mais (2) qu'entendez-vous par «nerveux» et (3) avez-vous défini une hauteur de ligne estimée? (J'essaie simplement de savoir s'il existe une meilleure solution qui vous permettrait de mettre à jour le tableau de manière dynamique.)x
à la dernière ligne de mon TableView ... mais parce que j'insère de nouvelles lignes, cela ne fonctionnera pas, je ne peux pas savoir quelle sera la fin de ma tableview avant de recharger les données.Réponses:
Pour éviter de sauter, vous devez enregistrer les hauteurs des cellules lors du chargement et donner une valeur exacte dans
tableView:estimatedHeightForRowAtIndexPath
:Rapide:
Objectif c:
la source
cellHeightsDictionary
:cellHeightsDictionary = [NSMutableDictionary dictionary];
estimatedHeightForRowAtIndexPath:
renvoie une valeur double peut provoquer une*** Assertion failure in -[UISectionRowData refreshWithSection:tableView:tableViewRowData:]
erreur. Pour le réparer, à lareturn floorf(height.floatValue);
place.Version Swift 3 de la réponse acceptée.
la source
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
, cela gère tout le calcul de hauteur dont j'ai besoin.UITableViewDelegate
à ma classe. Se conformer à ce protocole est nécessaire car il contient lawillDisplay
fonction indiquée ci-dessus . J'espère que je pourrai sauver quelqu'un de la même lutte.Le saut est dû à une mauvaise hauteur estimée. Plus le estiméRowHeight diffère de la hauteur réelle, plus la table peut sauter lorsqu'elle est rechargée, en particulier plus elle a été défilée vers le bas. En effet, la taille estimée du tableau diffère radicalement de sa taille réelle, ce qui oblige le tableau à ajuster la taille et le décalage de son contenu. Ainsi, la hauteur estimée ne doit pas être une valeur aléatoire mais proche de ce que vous pensez que la hauteur va être. J'ai également expérimenté quand je définis
UITableViewAutomaticDimension
si vos cellules sont du même type alorssi vous avez une variété de cellules dans différentes sections, je pense que le meilleur endroit est
la source
tableView(_:estimatedHeightForHeaderInSection:)
La réponse @Igor fonctionne bien dans ce cas, le
Swift-4
code de celui-ci.dans les méthodes suivantes de
UITableViewDelegate
la source
J'ai essayé toutes les solutions de contournement ci-dessus, mais rien n'a fonctionné.
Après avoir passé des heures et traversé toutes les frustrations possibles, j'ai trouvé un moyen de résoudre ce problème. Cette solution est un sauveur de vie! A travaillé comme un charme!
Swift 4
Je l'ai ajouté en tant qu'extension, pour rendre le code plus propre et éviter d'écrire toutes ces lignes à chaque fois que je veux recharger.
enfin ..
OU vous pouvez ajouter ces lignes à votre
UITableViewCell
awakeFromNib()
méthodeet fais normal
reloadData()
la source
reloadWithoutAnimation
mais où est lareload
partie?tableView.reloadData()
premier et ensuitetableView.reloadWithoutAnimation()
, cela fonctionne toujours.J'utilise plus de moyens pour résoudre ce problème:
Pour le contrôleur de vue:
comme extension pour UITableView
Le résultat est
la source
Je suis tombé sur ceci aujourd'hui et j'ai observé:
cellForRowAtIndexPath
n'aide pas.Le correctif était en fait assez simple:
Remplacez
estimatedHeightForRowAtIndexPath
et assurez-vous qu'il renvoie les valeurs correctes.Avec cela, tous les tremblements et sauts bizarres dans mes UITableViews se sont arrêtés.
REMARQUE: je connais en fait la taille de mes cellules. Il n'y a que deux valeurs possibles. Si vos cellules sont vraiment de taille variable, alors vous voudrez peut - être mettre en cache la
cell.bounds.size.height
detableView:willDisplayCell:forRowAtIndexPath:
la source
Vous ne pouvez en fait recharger que certaines lignes en utilisant
reloadRowsAtIndexPaths
, par exemple:Mais, en général, vous pouvez également animer les changements de hauteur de cellule du tableau comme ceci:
la source
Voici une version un peu plus courte:
la source
Remplacement de la méthode EstimatedHeightForRowAtIndexPath avec une valeur élevée, par exemple 300f
Cela devrait résoudre le problème :)
la source
Il y a un bogue qui, je crois, a été introduit dans iOS11.
C'est à ce moment-là que vous faites une
reload
tableViewcontentOffSet
est modifiée de manière inattendue. En faitcontentOffset
, ne devrait pas changer après un rechargement. Cela a tendance à se produire en raison d'erreurs de calculUITableViewAutomaticDimension
Vous devez enregistrer votre
contentOffSet
et le remettre à votre valeur enregistrée une fois votre rechargement terminé.Comment l'utilisez vous?
Cette réponse est tirée d' ici
la source
Celui-ci a fonctionné pour moi dans Swift4:
la source
Aucune de ces solutions n'a fonctionné pour moi. Voici ce que j'ai fait avec Swift 4 et Xcode 10.1 ...
Dans viewDidLoad (), déclarez la hauteur de ligne dynamique du tableau et créez des contraintes correctes dans les cellules ...
Aussi dans viewDidLoad (), enregistrez toutes vos nibs de cellule tableView dans tableview comme ceci:
Dans tableView heightForRowAt, renvoie une hauteur égale à la hauteur de chaque cellule à indexPath.row ...
Donnez maintenant une hauteur de ligne estimée pour chaque cellule dans tableView EstimatedHeightForRowAt. Soyez aussi précis que possible ...
Cela devrait fonctionner...
Je n'avais pas besoin d'enregistrer et de définir contentOffset lors de l'appel de tableView.reloadData ()
la source
J'ai 2 hauteurs de cellule différentes.
Après avoir ajouté estiméHeightForRowAt , il n'y avait plus de saut.
la source
Essayez d'appeler
cell.layoutSubviews()
avant de renvoyer la cellulefunc cellForRowAtIndexPath(_ indexPath: NSIndexPath) -> UITableViewCell?
. C'est un bogue connu dans iOS8.la source
Vous pouvez utiliser les éléments suivants dans
ViewDidLoad()
la source
J'avais ce comportement de saut et j'ai d'abord pu l'atténuer en définissant la hauteur exacte de l'en-tête estimée (car je n'avais qu'une vue d'en-tête possible), mais les sauts ont alors commencé à se produire spécifiquement à l' intérieur des en-têtes, n'affectant plus l'ensemble du tableau.
Suite aux réponses ici, j'ai eu l'indice qu'il était lié aux animations, donc j'ai trouvé que la vue de table était à l'intérieur d'une vue de pile, et parfois nous appelions à l'
stackView.layoutIfNeeded()
intérieur d'un bloc d'animation. Ma solution finale était de m'assurer que cet appel ne se produise pas à moins que "vraiment" nécessaire, car la mise en page "si nécessaire" avait des comportements visuels dans ce contexte même quand "pas nécessaire".la source
J'ai eu le même problème. J'avais des données de pagination et de rechargement sans animation mais cela n'aidait pas le défilement à éviter de sauter. J'ai une taille différente d'IPhones, le scroll n'était pas nerveux sur iphone8 mais il était nerveux sur iphone7 +
J'ai appliqué les modifications suivantes sur la fonction viewDidLoad :
et mon problème résolu. J'espère que cela vous aide aussi.
la source
L'une des approches pour résoudre ce problème que j'ai trouvé est
la source
En fait, je trouve que si vous utilisez
reloadRows
un problème de saut. Ensuite, vous devriez essayer d'utiliserreloadSections
comme ceci:la source