UITableViewCell 上的动画
Posted
技术标签:
【中文标题】UITableViewCell 上的动画【英文标题】:Animation on UITableViewCell 【发布时间】:2019-03-18 05:00:42 【问题描述】:我正在尝试将动画放在 UITableViewCell 中。动画是onClick table view cell将tableCell的frame变成tableview frame。
我有以下代码:
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
return 10;
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCell*cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
return cell;
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCell*cell = [tableView cellForRowAtIndexPath:indexPath];
if(cell.frame.size.height == tableView.bounds.size.height)
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
else
cell.frame = tableView.bounds;
[[cell superview] bringSubviewToFront:cell];
[UIView animateWithDuration:0.5 delay:0.0 usingSpringWithDamping:0.5 initialSpringVelocity:0.2 options:UIViewAnimationOptionCurveEaseOut animations:^
[self.view layoutIfNeeded];
completion:^(BOOL finished)
];
它工作正常,但在更改单元格的框架后,我也可以点击另一个我不想要的单元格。我怎样才能做到这一点?
【问题讨论】:
你的问题不清楚,你的意思是改变单元格的框架后我也可以点击另一个单元格? @vivekDas 请检查第二张图片,它是我更新的单元格。我禁用了表格视图滚动。如果我再次点击(假设在底部),则单元格(不是该单元格背面的这个单元格)被点击。清楚了吗? 我用过 [[cell superview] bringSubviewToFront:cell];成为选定单元格覆盖的方法 那么在过度单元格之后你想要什么?以及如何解除覆盖? @vivekDas 我想如果我再次点击打开的单元格,它应该会刷新并且它正在工作,但其他单元格也处于活动状态,这是我不想要的。我只想吸引当前单元格 【参考方案1】:一种可能的解决方案是声明一个变量,该变量将保存一个扩展单元格的 indexPath 数组,如下所示
// Will hold the indexPath of expanded cell
var expandedCell : [IndexPath] = []
第二件事是添加和删除已扩展/未扩展的单元格,为此您必须更新您的 UITableView Delegate didSelectRowAt
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
let index = expandedCell.firstIndex (localIndexPath) -> Bool in
return indexPath == localIndexPath
if let index = index
expandedCell.remove(at: index)
else
expandedCell.append(indexPath)
tableviewMessageList.reloadRows(at: [indexPath], with: .fade)
最后你必须添加另一个 UITableView Delegate heightForRowAt
来返回单元格的高度,如果单元格的 indexPath 在数组中,它将返回展开后的大小,否则返回单元格的正常大小,如下所示:-
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
if expandedCell.contains(indexPath)
return tableView.frame.height
return 200.0 //NormalHeight
注意:我的答案是 Swift,但同样的原则也适用于 Objective-C,你只需要更改语法。
【讨论】:
当有人在那里度过了宝贵的时间@Wdp 移动时,至少有礼貌的回应 这不是我所期望的。不好意思推迟了。我想要什么我想根据我的代码禁用未选择的单元格 如果没有错,您的代码只是在进行扩展和折叠【参考方案2】:总的来说,我认为更好的方法是使用单独的视图来全屏显示单元格详细信息,尽管您可能有一些限制要求您这样做。话虽如此,请在下面找到我的答案。
这是我收集到的您当前的问题是:
您希望显示展开的单元格,当处于展开状态时,触摸会通过单元格视图并点击其后面的表格视图并重新触发didSelectRowAtIndexPath:
tableview 委托方法(在展开后的其他单元格上一)。
这些是我看到的几个可能的解决方案:
-
在单元格展开时将点击手势识别器添加到单元格中,以便吸收触摸,然后在使用后移除手势识别器。
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapOnExpandedCell:)];
[cell addGestureRecognizer:tap];
cell.frame = tableView.bounds;
[[cell superview] bringSubviewToFront:cell];
UIView *bgView = [[UIView alloc] init];
bgView.backgroundColor = [UIColor purpleColor];
cell.selectedBackgroundView = bgView;
[UIView animateWithDuration:0.5 delay:0.0 usingSpringWithDamping:0.5 initialSpringVelocity:0.2 options:UIViewAnimationOptionCurveEaseOut animations:^
[self.view layoutIfNeeded];
completion:nil];
-(void)didTapOnExpandedCell:(UIGestureRecognizer *)recognizer
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:self.tableView.indexPathForSelectedRow];
// do whatever you were planning on doing when tapping on the
// expanded cell
[self.tableView reloadRowsAtIndexPaths:@[self.tableView.indexPathForSelectedRow] withRowAnimation:UITableViewRowAnimationNone];
[cell removeGestureRecognizer:recognizer];
-
继承 UITableViewCell 并覆盖 touchesBegan:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
R4NTableViewCell *cell = (R4NTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
cell.frame = tableView.bounds;
[[cell superview] bringSubviewToFront:cell];
UIView *bgView = [[UIView alloc] init];
bgView.backgroundColor = [UIColor purpleColor];
cell.selectedBackgroundView = bgView;
[UIView animateWithDuration:0.5 delay:0.0 usingSpringWithDamping:0.5 initialSpringVelocity:0.2 options:UIViewAnimationOptionCurveEaseOut animations:^
[self.view layoutIfNeeded];
completion:nil];
// in R4NTableViewCell.m implementation override touchesBegan
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
// if we're not selected, don't intercept the touch so the tableview can handle it
// calling back to super will give the default tableview behavior and get our delegate callback
if (self.selected == NO)
self.frameBeforeExpansion = self.frame;
[super touchesBegan:touches withEvent:event];
else // we're in the expanded state so intercept the touch
NSSet <UITouch *> *singleTouches = [[event allTouches] objectsPassingTest:^BOOL(UITouch * _Nonnull obj, BOOL * _Nonnull stop)
return obj.tapCount == 1;
];
if (singleTouches.count > 0)
// the user single tapped our view
[UIView animateWithDuration:1.0 delay:0.0 usingSpringWithDamping:0.7 initialSpringVelocity:0.2 options:UIViewAnimationOptionCurveEaseOut animations:^
self.frame = self.frameBeforeExpansion;
[self.superview layoutIfNeeded];
completion:^(BOOL finished)
[self setSelected:NO];
self.backgroundView.backgroundColor = [UIColor greenColor];
];
从您的解释中我并没有真正理解的另一件事(正如 cmets 所提到的)是当用户点击展开的 tableview 单元格时您期望发生的事情。
【讨论】:
@Wdpmobile 很高兴它有帮助。随意投票或标记为解决方案,以便其他人在访问此帖子时可以看到答案是有帮助的。以上是关于UITableViewCell 上的动画的主要内容,如果未能解决你的问题,请参考以下文章
UITableViewCell 上的圆形 UIImageView 在首次加载时不起作用
自定义 UITableViewCell 和 setSelected:animated 上的动画:
选择后,您可以为 UITableViewCell 上的高度变化设置动画吗?
如何淡入/淡出 UITableViewCell 上的 UILabel?