UITableViewCell GestureReognizer 的性能问题

Posted

技术标签:

【中文标题】UITableViewCell GestureReognizer 的性能问题【英文标题】:Performance Issue with UITableViewCell GestureReognizer 【发布时间】:2012-03-12 21:42:46 【问题描述】:

我向 UITableViewCells 添加了单击和双击手势识别器。但是在滚动表格几次之后,在我的滑动手势结束滚动表格和滚动动画开始之间的停顿变得越来越长。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    static NSString *CellIdentifier = @"tableViewCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) 
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    

    UITapGestureRecognizer* singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap:)];
    singleTap.numberOfTapsRequired = 1;
    singleTap.numberOfTouchesRequired = 1;
    [cell addGestureRecognizer:singleTap];

    UITapGestureRecognizer* doubleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doubleTap:)];
    doubleTap.numberOfTapsRequired = 2;
    doubleTap.numberOfTouchesRequired = 1;
    [singleTap requireGestureRecognizerToFail:doubleTap];
    [cell addGestureRecognizer:doubleTap];

    if (tableView == self.searchDisplayController.searchResultsTableView) 
        // search results
    
    else 
        // normal table
    

    return cell;

SingleTap: 和 doubleTap: 方法

- (void)singleTap:(UITapGestureRecognizer *)tap

    if (UIGestureRecognizerStateEnded == tap.state) 
        UITableViewCell *cell = (UITableViewCell *)tap.view;
        UITableView *tableView = (UITableView *)cell.superview;
        NSIndexPath* indexPath = [tableView indexPathForCell:cell];
        [tableView deselectRowAtIndexPath:indexPath animated:NO];
        // do single tap
    


- (void)doubleTap:(UITapGestureRecognizer *)tap

    if (UIGestureRecognizerStateEnded == tap.state) 
        UITableViewCell *cell = (UITableViewCell *)tap.view;
        UITableView *tableView = (UITableView *)cell.superview;
        NSIndexPath* indexPath = [tableView indexPathForCell:cell];
        [tableView deselectRowAtIndexPath:indexPath animated:NO];
        // do double tap
    

由于初始滚动很流畅,我尝试将手势识别器添加到 if (cell == nil) 条件中,但后来它们从未添加到单元格中。

我最初也将手势添加到 tableView 而不是单个单元格,但这会导致 searchDisplayController 出现问题,即点击无法识别的取消按钮。

如果有任何想法,我会很感激,谢谢。

【问题讨论】:

【参考方案1】:

cellForRowAtIndexPath 方法会为同一个 NSIndexPath 调用多次,因此您向单元格添加了太多手势识别器。因此性能会受到影响。

我的第一个建议是在表格视图中只添加一个手势识别器。 (我为一个类似的问题写了这个答案:https://***.com/a/4604667/550177)

但正如您所说,它会导致 searchDisplayController 出现问题。也许您可以通过 UIGestureRecognizerDelegate 的智能实现来避免它们(当点击不在单元格内时,在-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer; 中返回 NO)。

我的第二个建议:只添加一次手势识别器:

if ([cell.gestureRecognizers count] == 0) 
    // add recognizer for single tap + double tap

【讨论】:

谢谢,我刚刚意识到 if(cell==nil) 使用 ios5 和情节提要永远不会正确,并提出了与您的第二个建议相同的解决方案,并且效果很好。但我更喜欢你的第一个想法,我会尝试一下。

以上是关于UITableViewCell GestureReognizer 的性能问题的主要内容,如果未能解决你的问题,请参考以下文章

在 iOS 中使用 UIScrollView 添加 UIGestureRecognizer

我可以禁用UIPageViewController的页面边框手势识别器吗?刷卡一个?

UITableViewCell 中的 UIDatePicker 更新 UITableViewCell 文本标签

突出显示的 UITableViewCell 和选定的 UITableViewCell 有啥区别?

斯威夫特 - UITableViewCell?不能转换为 UITableViewCell

UITableviewcell的性能问题