改变 UITableViewCell 高度的自定义动画
Posted
技术标签:
【中文标题】改变 UITableViewCell 高度的自定义动画【英文标题】:Custom animation for changing height of UITableViewCell 【发布时间】:2014-02-09 09:57:36 【问题描述】:我想用 UIView 动画制作改变 UITableViewCell 高度的动画(将来用 spring 动画)。
所以我有:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = (UITableViewCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.backgroundColor = [UIColor greenColor];
UILabel *viewLabel = [[UILabel alloc] initWithFrame:CGRectMake(10.0f, 10.0f, [[UIScreen mainScreen] bounds].size.width, 40.0f)];
viewLabel.text = @"Test";
viewLabel.backgroundColor = [UIColor clearColor];
[cell.contentView addSubview:viewLabel];
return cell;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
[tableView beginUpdates];
[self animateCell:indexPath andTableView:tableView];
[tableView endUpdates];
- (void)animateCell:(NSIndexPath*)indexPath andTableView:(UITableView*)tableView
[UIView animateWithDuration:1.0f animations: ^
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
CGRect rect = cell.frame;
rect.size.height = 90.0f;
cell.frame = rect;
NSLog(@"%f", cell.frame.size.height);
];
但它不起作用。但如果我要添加:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
if ([indexPath isEqual:[tableView indexPathForSelectedRow]])
return 90.0f;
return 40.0f;
我看到单元格正在改变它的高度,并且动画被应用于在 animateCell 方法中创建的自定义单元格
【问题讨论】:
调用 endUpdates 时,UITableView 执行默认动画。动画属性基于表格视图的数据源值。 所以我不需要调用 beginUpdates 和 endUpdates 并处理自定义动画(将附近单元格的位置更改为动画单元格)? 你的动画应该是什么? 用弹跳效果改变选中单元格的高度(新的 UIView 动画有弹簧效果) 【参考方案1】:我认为你不应该使用beginUpdate
/endUpdates
方法并在调用reloadData
之前手动执行动画。单元格的最终状态(动画后)由数据源定义。这是tableView:didSelectRowAtIndexPath:
中的动画示例
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
_selectedIndexPath = indexPath;
[UIView animateWithDuration:1 animations:^
// move down cells which are below selected one
for (UITableViewCell *cell in tableView.visibleCells)
NSIndexPath *cellIndexPath = [tableView indexPathForCell:cell];
if (cellIndexPath.row > indexPath.row)
CGRect frame = cell.frame;
frame.origin.y += kTargetHeight - tableView.rowHeight;
cell.frame = frame;
// expand selected cell
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
CGRect frame = cell.frame;
frame.size.height = kTargetHeight;
cell.frame = frame;
completion:^(BOOL finished)
[tableView reloadData]; // commit final state
];
选中单元格的最终状态:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
if ([indexPath isEqual:_selectedIndexPath])
return kTargetHeight;
return tableView.rowHeight;
【讨论】:
谢谢,它可以工作,但是由于 [tableView reloadData] 会出现闪烁 谢谢,它可以工作,但是由于[tableView reloadData]会出现闪烁,这看起来更好:[tableView beginUpdates]; [tableView endUpdates]; 你知道,对 didDeselectRowAtIndexPath: 做了类似的操作,但不起作用 缩小单元格时也会出现问题。如果列表中的单元格多于列表,则最后一个(虚拟)单元格将无法通过 tableView.visibleCells 访问。随着单元格变小,您会在底部看到一个间隙,直到动画完成并添加底部的虚拟单元格。以上是关于改变 UITableViewCell 高度的自定义动画的主要内容,如果未能解决你的问题,请参考以下文章
在 UITableView 中定义高度的自定义 UITableViewCell
从 -tableView:cellForRowAtIndexPath: 计算“indexPath”处的自定义 UITableViewCell 高度:?
UIImageView 在具有不同高度的自定义 UITableViewCell 内自动调整大小
在具有动态高度的 IB uitableviewcell 中使用带有 XIB 的自定义视图