【问题标题】:UITableViewCell animate resize when user touchdown or tap CellUITableViewCell 在用户触地或点击单元格时动画调整大小
【发布时间】:2020-05-30 06:15:59
【问题描述】:

我想在 detailViewController 显示之前为 UITableViewCell 设置动画,如下图所示(单元格的尺寸变小)。我从过去两天开始尝试过,并尝试了我为类似问题找到的其他所有答案。

我希望一旦用户将手指放在 UITableViewCell 上,单元格就会设置动画/调整大小。

UITableViewCell 是一个自定义单元格。我尝试在 UITableViewCell 子类的 setSelected:(BOOL)selected animated:(BOOL)animated 方法中为 cell.contentView 设置一个新框架。 UITableViewCell 没有像我预期的那样调整大小。

我还观察到当用户从 UITableViewCell 抬起手指时调用此方法。实际上,我希望它在用户点击单元格时立即发生。如果未选择单元格并且用户移动到其他单元格,则单元格应重新调整为正常大小。

然后我做了一些关于从 UITableViewCell 接收触摸事件的搜索。我尝试添加一个UILongPressGestureRecognizer and UITapGestureRecognizer 并在选择器中尝试像这样更改 cell.contentView 框架

cell.contentView.frame = CGRectMake(cell.frame.origin.x +20, cell.frame.origin.y, cell.frame.size.width-20, cell.frame.size.height);
[cell setNeedsDisplay];

但是选定的单元格只是闪烁(单元格背景)它没有像我预期的那样调整大小。

任何建议都会很有帮助。在此先感谢

【问题讨论】:

    标签: ios objective-c iphone uitableview


    【解决方案1】:

    这是在 Swift 5.0 中点击单元格动画的更简单方法:

    func tableView(_ tableView: UITableView, didHighlightRowAt indexPath: IndexPath)
    {
        let cell = tableView.cellForRow(at: indexPath)
    
        UIView.animate(withDuration: 0.3) {
    
            cell!.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
        }
    }
    
    func tableView(_ tableView: UITableView, didUnhighlightRowAt indexPath: IndexPath)
    {
        let cell = tableView.cellForRow(at: indexPath)
    
        UIView.animate(withDuration: 0.3) {
    
            cell!.transform = .identity
        }
    }
    

    【讨论】:

      【解决方案2】:

      好的,在阅读了一些文档并浏览了 WWDC 视频之后,我能够解决这个问题。

      我学到了一件重要的事情。

      切勿在启用 AutoLayoutEnabled 的视图上使用 setFrame:。

      牢记这一点,我将自定义 UITableViewCell xib 更改为使用 AutoResizing 掩码。然后在我的 UITableViewController 中我使用了这些 tableView:didHighlightRowAtIndexPath: tableView:didUnHighlightRowAtIndexPath: 代表

      这是来自我的视图控制器的代码 sn-p。

              -(void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath
          {
      
              NSLog(@"I'm Highlighted at %ld",(long)indexPath.section);
              CustomTableViewCell *cell = (CustomTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath];
      
              originalCellSize = cell.frame;
      
      //Using animation so the frame change transform will be smooth.
      
              [UIView animateWithDuration:0.1f animations:^{
      
                  cell.frame = CGRectMake(cell.frame.origin.x +20, cell.frame.origin.y, cell.frame.size.width-40, cell.frame.size.height);
              }];
      
          }
      
      
          -(void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath
          {
              CustomTableViewCell *cell = (CustomTableViewCell *)[self.tableableView cellForRowAtIndexPath:indexPath];
      
      
              [UIView animateWithDuration:0.1f animations:^{
                  cell.frame = CGRectMake(0, originalCellSize.origin.y, self.view.bounds.size.width, 180) ;
              }];
      
              originalCellSize = CGRectMake(0, 0, 0, 0);
          }
      

      【讨论】:

      • 感谢您发布对您自己问题的跟进。
      【解决方案3】:

      我试图实现与您类似的目标。我试图在我添加到自定义 UITableViewCell 的 UIImageView 中显示我的 UIImage 的一部分,并设置了约束以使我的 imageview 具有单元格的整个大小(类似于背景,特别是当您有一个自定义单元格时出色地)。我遵循@Joy 为this question 提供的答案,并创建了以下内容:

      我将此添加到我的viewDidLoad

      self.currentSelection = -1;
      // I changed his line below, so that the image resizing (cell resizing really) is constant for 
      //all my images. I guess you can use this to resize your background back and forth to whatever size you want to.
      self.newCellHeight = self.tableView.frame.size.width*3/2;
      

      然后我添加了这些:

      -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
      
      //I added this to toggle a tap-tapagain kind of thing, so if the same cell is tapped twice, first tap expands and second tap collapses.  
          if (self.currentSelection==indexPath.row) {
              self.currentSelection = -1;
          }else{
              self.currentSelection = indexPath.row;
          }
              // save height for full text label
      //    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
      
              // animate
              [tableView beginUpdates];
              [tableView endUpdates];
      
      }
      //The rest is pretty much the same as his code
      - (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
          // do things with your cell here
      
          // sentinel
          self.currentSelection = -1;
      
          // animate
          [tableView beginUpdates];
          [tableView endUpdates];
      }
      
      - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
          int rowHeight;
          if ([indexPath row] == self.currentSelection) {
              rowHeight = self.newCellHeight;
          } else rowHeight = 100;
          return rowHeight;
      }
      

      最后一件事,如果您想将背景显示为居中,并从中心“放大”和缩小。我将我的 imageview 内容模式设置为居中,如下所示:

      [cell.myImageView setContentMode:UIViewContentModeCenter];
      

      我从@EmptyStack 和@erkanyildiz 对this question 的回答中学到了很多东西。

      无论如何,我希望这对您有所帮助,如果没有任何相关内容,我们深表歉意! :)

      【讨论】:

        【解决方案4】:

        试试这个

        - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath)path
        // or it must be some other method
        {
          [self.tableView beginUpdates];
          [[self.tableView reloadRowsAtIndexPaths:@[path] withRowAnimation:rowAnimation];
          [self.tableView endUpdates];
        }
        

        在您的表格视图委托方法中,您必须知道选择了哪个单元格。

        - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath)path
        {
          YourTableClass *cell=[tableView cellForRowAtIndexPath:path];
          if(cell.isTaped)
            return increasedHeight;
          else
            return defaultHeight;
        } 
        

        【讨论】:

        • didSelectRowAtIndexPath 在用户将手指从屏幕上移开时被调用。我什至尝试过 willSelectRowAtIndexPath。它不会在收到点击后立即通知我。
        • 在 heightForRowAtIndexPath 中调用 cellForRowForAtIndexPath 会使你的程序崩溃。看到这个stackoverflow.com/a/12653203/1032179
        猜你喜欢
        • 1970-01-01
        • 2013-07-15
        • 1970-01-01
        • 2015-03-20
        • 1970-01-01
        • 2015-09-16
        • 1970-01-01
        • 2013-05-26
        • 1970-01-01
        相关资源
        最近更新 更多