UITableViewCell 滚动时的动画
我已经实现了 Cocoa with Love 的 多行选择示例 其中涉及创建一个自定义 UITableViewCell,该 UITableViewCell 在layoutSubviews中启动动画以在每行左侧显示复选框,如下所示:
- (void)layoutSubviews
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[super layoutSubviews];
if (((UITableView *)self.superview).isEditing)
{
CGRect contentFrame = self.contentView.frame;
contentFrame.origin.x = EDITING_HORIZONTAL_OFFSET;
self.contentView.frame = contentFrame;
}
else
{
CGRect contentFrame = self.contentView.frame;
contentFrame.origin.x = 0;
self.contentView.frame = contentFrame;
}
[UIView commitAnimations];
}
这工作正常,并且对于所有意图和目的,我的 UITableView 都会按其应有的方式行事。然而,我遇到了一个小的美学问题:当滚动之前未显示的 UITableView 行时,将启动其滑动动画,这意味着某些行在进入视图时动画是交错的。
这是可以理解的,因为 setAnimationBeginsFromCurrentState 已设置为 YES,并且 UITableView 中更下方的行尚未更新其帧位置。为了解决这个问题,我尝试使用 willDisplayCell 来覆盖 UITableView 处于编辑模式时变得可见的单元格的动画。本质上绕过动画并立即更新行框架,以便使其看起来好像单元格已经动画到位,如下所示:
/*
Since we animate the editing transitions, we need to ensure that all animations are cancelled
when a cell is scheduled to appear, so that things happen instantly.
*/
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
[cell.contentView.layer removeAllAnimations];
if(tableView.isEditing) {
CGRect contentFrame = cell.contentView.frame;
contentFrame.origin.x = EDITING_HORIZONTAL_OFFSET;
cell.contentView.frame = contentFrame;
} else {
CGRect contentFrame = cell.contentView.frame;
contentFrame.origin.x = 0;
cell.contentView.frame = contentFrame;
}
}
不幸的是,这似乎没有任何效果。有谁知道我如何解决这个问题?
I've implemented Cocoa with Love's example for Multi-row selection which involves creating a custom UITableViewCell that initiates an animation in layoutSubviews to display checkboxes to the left of each row, like so:
- (void)layoutSubviews
{
[UIView beginAnimations:nil context:nil];
[UIView setAnimationBeginsFromCurrentState:YES];
[super layoutSubviews];
if (((UITableView *)self.superview).isEditing)
{
CGRect contentFrame = self.contentView.frame;
contentFrame.origin.x = EDITING_HORIZONTAL_OFFSET;
self.contentView.frame = contentFrame;
}
else
{
CGRect contentFrame = self.contentView.frame;
contentFrame.origin.x = 0;
self.contentView.frame = contentFrame;
}
[UIView commitAnimations];
}
This works fine and for all intents and purposes my UITableView acts as it should. However I'm running into a small aesthetic issue: when scrolling my UITableView rows which have not previously been displayed will initiate their sliding animation, meaning the animation is staggered for certain rows as they come into view.
This is understandable, given that setAnimationBeginsFromCurrentState has been set to YES and rows further down in the UITableView have yet to have their frame position updated. To solve the issue, I attempted to use willDisplayCell to override the animation for cells which become visible while the UITableView is in edit mode. Essentially bypassing the animation and updating the rows frame immediately, so as to make it appear as if the cell has already animated into place, like so:
/*
Since we animate the editing transitions, we need to ensure that all animations are cancelled
when a cell is scheduled to appear, so that things happen instantly.
*/
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
[cell.contentView.layer removeAllAnimations];
if(tableView.isEditing) {
CGRect contentFrame = cell.contentView.frame;
contentFrame.origin.x = EDITING_HORIZONTAL_OFFSET;
cell.contentView.frame = contentFrame;
} else {
CGRect contentFrame = cell.contentView.frame;
contentFrame.origin.x = 0;
cell.contentView.frame = contentFrame;
}
}
Unfortunately this doesn't seem to have any effect. Does anyone have any idea as to how I can solve this issue?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不确定您是否仍然需要这个问题的答案,但我刚刚遇到了完全相同的问题,所以我想我会分享我的解决方案。我按照您提到的 Cocoa with Love 博客文章中描述的方式实现了多重选择。
在 cellAtIndexPath DataSource 方法中,当我创建一个新单元格(如果该单元格已经在可重用单元格队列中)时,我检查 tableView 是否处于编辑模式,如果是,我在单元格上设置一个属性(我创建了自己的属性)具有 EnableAnimation 属性的自定义单元格)设置为 false,因此当它获取 SetEditing 回调时,它不会为单元格设置动画,而只会设置框架。在 Cell 类的构造函数中,我将 EnableAnimation 设置为 true,当调用 SetEditing 回调时,我将 EnableAnimation 设置为传入的 animate 参数。我希望这会有所帮助。
Not sure if you still need an answer to this question but I just ran into the exact same issue so I thought that I would share my solution. I implemented Multi-Selection the same way its described in the Cocoa with Love blog post that you mentioned.
In the cellAtIndexPath DataSource method when I create a new cell (not if the cell is already in the Queue of reusable cells) I check if the tableView is in editing mode and if it is I set a property on the cell (I created my own custom cell with an EnableAnimation property) to false so when it gets the SetEditing callback it will not animate the cell, instead it will just set the frame. In the constructor of the Cell class I set EnableAnimation to true, when the SetEditing callback is called I set EnableAnimation to the animate argument that is passed in. I hope this helps.