Dav*_*vid 124 uitableview ios autolayout swift
我觉得这可能是一个普遍的问题,并且想知道是否有任何共同的解决方案.
基本上,我的UITableView具有每个单元格的动态单元格高度.如果我不在UITableView和我的顶部tableView.reloadData()
,向上滚动变得有点跳跃.
我相信这是因为我重新加载数据,因为我正在向上滚动,UITableView会重新计算每个进入可见性的单元格的高度.如何缓解这种情况,或者如何仅将数据从某个IndexPath重新加载到UITableView的末尾?
此外,当我设法一直滚动到顶部时,我可以向下滚动然后向上滚动,没有跳跃没问题.这很可能是因为已经计算了UITableViewCell高度.
Igo*_*gor 187
为了防止跳跃,你应该在加载时保存单元格的高度,并给出准确的值tableView:estimatedHeightForRowAtIndexPath
:
// declare cellHeightsDictionary
NSMutableDictionary *cellHeightsDictionary;
// initialize in code (thanks to @Gerharbo)
cellHeightsDictionary = @{}.mutableCopy;
// declare table dynamic row height and create correct constraints in cells
tableView.rowHeight = UITableViewAutomaticDimension;
// save height
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
[cellHeightsDictionary setObject:@(cell.frame.size.height) forKey:indexPath];
}
// give exact height value
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
NSNumber *height = [cellHeightsDictionary objectForKey:indexPath];
if (height) return height.doubleValue;
return UITableViewAutomaticDimension;
}
Run Code Online (Sandbox Code Playgroud)
Cas*_*ner 104
Swift 3版本接受了答案.
var cellHeights: [IndexPath : CGFloat] = [:]
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cellHeights[indexPath] = cell.frame.size.height
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return cellHeights[indexPath] ?? 70.0
}
Run Code Online (Sandbox Code Playgroud)
Kri*_*ore 36
跳跃是因为估计的高度不好.estimatedRowHeight与实际高度的差异越大,表重新加载时表可能跳得越多,尤其是滚动得越远.这是因为表的估计大小与其实际大小完全不同,迫使表调整其内容大小和偏移量.所以估计的高度不应该是随机值,而是接近你认为的高度.我也经历过,UITableViewAutomaticDimension
如果你的细胞是同一类型的话
func viewDidLoad() {
super.viewDidLoad()
tableView.estimatedRowHeight = 100//close to your cell height
}
Run Code Online (Sandbox Code Playgroud)
如果你在不同的部分有各种各样的细胞,那么我认为更好的地方是
func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
//return different sizes for different cells if you need to
return 100
}
Run Code Online (Sandbox Code Playgroud)
Kir*_*nee 25
@Igor的答案在这种情况下工作得很好Swift-4
,它的代码.
// declaration & initialization
var cellHeightsDictionary: [IndexPath: CGFloat] = [:]
Run Code Online (Sandbox Code Playgroud)
在以下方法中 UITableViewDelegate
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
// print("Cell height: \(cell.frame.size.height)")
self.cellHeightsDictionary[indexPath] = cell.frame.size.height
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
if let height = self.cellHeightsDictionary[indexPath] {
return height
}
return UITableViewAutomaticDimension
}
Run Code Online (Sandbox Code Playgroud)
Sru*_*mha 18
我已经尝试了上面的所有解决方法,但没有任何效果.
在花了几个小时并经历所有可能的挫折之后,找到了解决这个问题的方法.这个解决方案是生命救星!像魅力一样工作!
斯威夫特4
let lastContentOffset = tableView.contentOffset
tableView.beginUpdates()
tableView.endUpdates()
tableView.layer.removeAllAnimations()
tableView.setContentOffset(lastContentOffset, animated: false)
Run Code Online (Sandbox Code Playgroud)
我将它添加为扩展,以使代码看起来更干净,并避免每次我想重新加载时写下所有这些行.
extension UITableView {
func reloadWithoutAnimation() {
let lastScrollOffset = contentOffset
beginUpdates()
endUpdates()
layer.removeAllAnimations()
setContentOffset(lastScrollOffset, animated: false)
}
}
Run Code Online (Sandbox Code Playgroud)
终于..
tableView.reloadWithoutAnimation()
Run Code Online (Sandbox Code Playgroud)
Mar*_*Wan 11
我今天碰到了这个并观察到:
cellForRowAtIndexPath
没有帮助.修复实际上非常简单:
覆盖estimatedHeightForRowAtIndexPath
并确保它返回正确的值.
有了这个,我的UITableViews中所有奇怪的抖动和跳跃都停止了.
注意:我实际上知道我的细胞的大小.只有两个可能的值.如果您的单元格是真正可变大小的,那么您可能希望缓存cell.bounds.size.height
fromtableView:willDisplayCell:forRowAtIndexPath:
ras*_*slv 10
我使用更多的方法来解决它:
对于视图控制器:
var cellHeights: [IndexPath : CGFloat] = [:]
func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
cellHeights[indexPath] = cell.frame.size.height
}
func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return cellHeights[indexPath] ?? 70.0
}
Run Code Online (Sandbox Code Playgroud)
作为UITableView的扩展
extension UITableView {
func reloadSectionWithouAnimation(section: Int) {
UIView.performWithoutAnimation {
let offset = self.contentOffset
self.reloadSections(IndexSet(integer: section), with: .none)
self.contentOffset = offset
}
}
}
Run Code Online (Sandbox Code Playgroud)
结果是
tableView.reloadSectionWithouAnimation(section: indexPath.section)
Run Code Online (Sandbox Code Playgroud)
实际上,您可以使用reloadRowsAtIndexPaths
,例如重新加载某些行:
tableView.reloadRowsAtIndexPaths(indexPathArray, withRowAnimation: UITableViewRowAnimation.None)
Run Code Online (Sandbox Code Playgroud)
但是,通常,您还可以为表格单元格高度更改设置动画,如下所示:
tableView.beginUpdates()
tableView.endUpdates()
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
37610 次 |
最近记录: |