我的桌面视图中rowHeight
的更改动画有问题。动画在iPad 3(第一代视网膜)上花费很长时间(约3秒)。但是,当桌面视图靠近列表的中间到底部或减少时,如果我 展开 rowHeight
,则只需要很长时间列表中间的rowHeight
。当它位于顶部时,动画效果很好。注意事项:
UITableView
并重写setEditing:animated
方法,这是我更改rowHeight的地方。tableView:heightForRowAtIndexPath:
,因为我的表可以拥有用户想要的行数。如果导入数据,某些用户甚至可能拥有数十万行。30.0f
),其中我显示每个单元格的一系列选项(如#"删除","复制& #34;," print"," share"等。)beginUpdates
& endUpdates
)而只是简单地调用reloadData
,则更改是即时的。当然,那时没有动画。[self reloadRowsAtIndexPaths:self.indexPathsForVisibleRows withRowAnimation:UITableViewRowAnimationAutomatic]
无效(需要永久)。beginUpdates
& endUpdates
几乎在代码中的每个可能的位置,都没有效果。contentOffset
,但结果却产生了一些奇怪的效果,比如没有刷新tableCell等等。tableView:cellForRowAtIndexPath:
上。所以我记录了动画期间调用tableView:cellForRowAtIndexPath:
的次数:
scrollToRowAtIndexPath:atPosition:animated
: 59次。scrollToRowAtIndexPath:atPosition:animated
: 67次。reloadData
代替beginUpdates
& endUpdates
: 8次。这里是代码,非常简单,真的:
- (void) setEditing:(BOOL)editing animated:(BOOL)animated{
CGPoint point = CGPointMake(1, _sectionView.superview ? _sectionView.bounds.size.height + 1 + self.bounds.origin.y : 1 + self.bounds.origin.y);
NSIndexPath *path = [self indexPathForRowAtPoint:point];
[super setEditing:editing animated:animated];
CGFloat rowHeight = self.viewType.viewHeight.floatValue + (self.editing ? FlxRecordTableCellEditingHeight : 0);
self.rowHeight = rowHeight;
[self beginUpdates];
[self endUpdates];
// [self reloadData];
[self scrollToRowAtIndexPath:path atScrollPosition:UITableViewScrollPositionTop animated:NO];
// [self reloadRowsAtIndexPaths:self.indexPathsForVisibleRows withRowAnimation:UITableViewRowAnimationAutomatic];
}
当更改rowHeight
时,UITableView
会计算当前contentOffset
的新行,然后尝试设置这些新行的动画(包括其间的所有行)即使我告诉它移动到它开始的相同单元格。我怀疑如果我要增加rowHeight的更改(例如,从30.0f
到45.0f
),问题会变得更糟,因为UITableView
必须为更多行设置动画更改。我想要的是UITableView
首先移动到新单元格然后仅为那些单元格设置更改动画。但是,我似乎找不到办法做到这一点。
更新
神圣的{favorite_euphamism}! ......我一直试图提高tableView:cellForRowAtIndexPath
效率,但无济于事。所以我单独计算了tableView:cellForRowAtIndexPath
结束创建新单元格的次数(而不是重复使用它们)。在动画期间,UITableView
并不仅仅需要59到67次请求单元格,它通过返回{创建 59-67 新单元格 {1}} nil
。难怪它花了这么长时间......而且它也惹恼了我的记忆(感谢Xcode 5展示了......)。虽然我尽可能多地完成了我的细胞效率,但它们仍然是复杂的视图,并且绝对 设计用于那么多的创作。要解决这个问题......
任何帮助或想法将不胜感激。谢谢!
答案 0 :(得分:0)
所以,我提出的解决方案是最好的黑客,但它暂时正在工作。根据{{3}},Apple可能已经解决了即将推出的iOS 7.1更新问题,但我还没有搞砸测试版,所以我无法确认。
不幸的是,我被迫实施tableView:heightForRowAtIndexPath:
。我不想,但幸运的是大多数人已经更新到iOS 7,我可以在estimatedRowHeight
上有条件地使用UITableView
属性(仅限iOS 7)来缓解iOS 7大表的性能问题......每一个人都被搞砸了。我接近将我的应用程序设为“仅限iOS 7”,因此长时间(或非常多用户)不会出现问题。
我在课程中添加了3个新的iVar:CGFloat _rowHeight
,CGFloat _imminentRowHeight
和NSIndexPath *_anchorPath
。默认情况下返回_rowHeight
变量。但是,如果设置了_anchorPath
,则tableView:heightForRowAtIndexPath:
会在_imminentRowHeight
时有条件地返回indexPath.row >= _anchorPath.row
。这样可以在转换期间保持contentOffset
的{{1}}相同,以便_anchorPath
不会尝试通过几十个tableview单元格进行动画制作,这是原始问题:
UITableView
我创建了一种新方法来分离我的逻辑- (CGFloat) tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if (_anchorPath){
return indexPath.row >= _anchorPath.row ? _imminentRowHeight : _rowHeight;
}
return _rowHeight;
}
。我想再次指出这是updateRowHeight
的子类,所以如果您从视图控制器执行此操作,请将UITableView
替换为您的self
iVar:
_tableView
有些注意事项:
- (void) updateRowHeight{
CGFloat cellHeight = self.viewType.viewHeight.floatValue;
CGPoint anchorPoint = CGPointMake(1, _sectionView.superview ? _sectionView.bounds.size.height + 1 + self.bounds.origin.y : 1 + self.bounds.origin.y);
_anchorPath = [self indexPathForRowAtPoint:anchorPoint];
_imminentRowHeight = cellHeight + (self.editing ? FlxRecordTableCellEditingHeight : 0);
if (!_anchorPath){
_rowHeight = _imminentRowHeight;
if ([self respondsToSelector:@selector(estimatedRowHeight)]){
self.estimatedRowHeight = _rowHeight;
}
return;
}
if (_imminentRowHeight == _rowHeight) return;
[CATransaction begin];
[CATransaction setCompletionBlock:^{
_rowHeight = _imminentRowHeight;
NSIndexPath *anchor = _anchorPath;
_anchorPath = nil;
if ([self respondsToSelector:@selector(estimatedRowHeight)]){
self.estimatedRowHeight = _rowHeight;
}
[self reloadData];
[self scrollToRowAtIndexPath:anchor atScrollPosition:UITableViewScrollPositionTop animated:NO];
}];
[self beginUpdates];
[self endUpdates];
//We must scroll the anchor Path into the top position so that when we reload the table data positions don't change
[self scrollToRowAtIndexPath:_anchorPath atScrollPosition:UITableViewScrollPositionTop animated:YES];
[CATransaction commit];
}
必须在这里做很多工作,所以除非必要,否则最好不要做这项工作。UITableView
来设置动画上下文,以便我可以将完成块附加到它上面。 CATransaction
将使用当前动画上下文(如果有),否则它将创建自己的...非常方便。begin/endUpdates
认为锚点路径“上方”的所有内容都具有前一行(和不正确的行)高度。这就是我在重新加载表之前设置UITableView
和_rowHeight = _imminentRowHeight;
的原因。然后我必须在重新加载后滚动到锚点路径(不是动画),因为锚点路径的偏移量已经改变,因为所有先前的行都有新的行高。