UITableViewCell上的动画

问题描述 投票:0回答:2

我试图将动画放在UITableViewCell中。动画是onClick表视图单元格将tableCell的框架更改为tableview框架。

我有以下代码:

-(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) {

    }];
}

它工作正常,但在更改单元格的框架后,我能够点击另一个我不想要的单元格。我怎样才能做到这一点?

enter image description here

enter image description here

ios objective-c uitableview animation
2个回答
2
投票

一种可能的解决方案是声明一个变量,它将保存扩展单元格的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,您只需要更改语法。


0
投票

总的来说,我认为更好的方法是使用单独的视图来全屏显示单元格详细信息,尽管您可能有一些限制要求您这样做。话虽如此,请在下面找到我的答案。

这是我收集你当前的问题是:

您希望显示扩展的单元格,并且当处于扩展状态时,触摸将通过单元格视图并触及其后面的表格视图并重新触发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];
            }];
        }
    }
}

我在你的解释中没有真正理解的另一件事(正如所提到的评论)是你期望在用户点击扩展的tableview单元格时发生的事情。

© www.soinside.com 2019 - 2024. All rights reserved.