【问题标题】:Animation on UITableViewCellUITableViewCell 上的动画
【发布时间】: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 我想如果我再次点击打开的单元格,它应该会刷新并且它正在工作,但其他单元格也处于活动状态,这是我不想要的。我只想吸引当前单元格

标签: ios objective-c uitableview animation


【解决方案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 委托方法(在展开后的其他单元格上一)。

这些是我看到的几个可能的解决方案:

  1. 在单元格展开时将点击手势识别器添加到单元格中,以便吸收触摸,然后在使用后移除手势识别器。

-(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];
}
  1. 继承 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 很高兴它有帮助。随意投票或标记为解决方案,以便其他人在访问此帖子时可以看到答案是有帮助的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-01
相关资源
最近更新 更多