使用向后滑动手势以交互方式取消选择选定单元格

Posted

技术标签:

【中文标题】使用向后滑动手势以交互方式取消选择选定单元格【英文标题】:Interactively deselect selected cell with swipe back gesture 【发布时间】:2014-05-27 16:19:05 【问题描述】:

在“设置”等应用程序中,当您点击推动屏幕的单元格,然后从屏幕左侧向后滑动时,您可以看到所选单元格的背景颜色褪色的取消选择,并且它是完全交互式的 - 如果您滑动一半然后向后滑动选定的背景视图将恢复为完全不透明。

在我的应用程序中,我没有更改任何默认行为,当我从左侧滑动返回时,选定的单元格背景颜色保持完全不透明,直到滑动手势完成,然后它迅速淡化为取消选择它。

如何通过滑动返回手势实现交互式取消选择单元格?

【问题讨论】:

您正在寻找的 UITableViewController 上是否有 clearsSelectionOnViewWillAppear 方法? clearsSelectionOnViewWillAppear 默认设置为 YES。我没有把它改成NO。将其更改为 NO 将永远不会将其淡化为白色 - 在您以编程方式取消选择之前,它将始终保持选中状态。 【参考方案1】:

要在 ios 11 及更高版本中启用交互式取消选择,您可以使用 UITableViewController,因为它会为您实现它,或者您可以通过在转换协调器旁边为取消选择设置动画来实现它,如下所示:

- (void)viewWillAppear:(BOOL)animated  
    [super viewWillAppear:animated]; 

    NSIndexPath *selectedIndexPath = [self.tableView indexPathForSelectedRow];
    if (selectedIndexPath) 
        if (self.transitionCoordinator)  
            [self.transitionCoordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context)  
                [self.tableView deselectRowAtIndexPath:selectedIndexPath animated:YES]; 
             completion:^(id<UIViewControllerTransitionCoordinatorContext> context)  
                 if (context.cancelled)  
                     [self.tableView selectRowAtIndexPath:selectedIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; 
                  
            ]; 
         else  
             [self.tableView deselectRowAtIndexPath:selectedIndexPath animated:animated]; 
        
    

在 Swift 中:

override func viewWillAppear(_ animated: Bool) 
    super.viewWillAppear(animated)

    if let selectedIndexPath = tableView.indexPathForSelectedRow 
        if let coordinator = transitionCoordinator 
            coordinator.animate(alongsideTransition:  context in
                self.tableView.deselectRow(at: selectedIndexPath, animated: true)
            )  context in
                if context.isCancelled 
                    self.tableView.selectRow(at: selectedIndexPath, animated: false, scrollPosition: .none)
                
            
         else 
            self.tableView.deselectRow(at: selectedIndexPath, animated: animated)
        
    

类似的实现适用于UICollectionView

override func viewWillAppear(_ animated: Bool) 
    super.viewWillAppear(animated)

    if let indexPath = collectionView.indexPathsForSelectedItems?.first 
        if let coordinator = transitionCoordinator 
            coordinator.animate(alongsideTransition:  _ in
                self.collectionView.deselectItem(at: indexPath, animated: true)
            , completion:  context in
                if context.isCancelled 
                    self.collectionView.selectItem(at: indexPath, animated: false, scrollPosition: [])
                
            )
         else 
            collectionView.deselectItem(at: indexPath, animated: animated)
        
    

【讨论】:

【参考方案2】:

似乎clearsSelectionOnViewWillAppear 可能实际上被viewDidAppear: 调用而不是viewWillAppear: 只有在转换完全结束时才会发生更改,并且如果您取消交互式转换,它根本不会发生(如果它在viewWillAppear:,它会)。这看起来像一个 UIKit 错误,因为文档明确指出它应该在 viewWillAppear: 中被调用

将以下代码行放入viewWillAppear:,您将获得您正在寻找的确切行为,我刚刚尝试过。这可能是属性触发的确切行为,只是方法错误。

[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];

【讨论】:

太棒了。谢谢!我将提交错误报告并将其发送给 Apple。 @Joey Apple 是否解决了您发布的雷达问题,或者您可以将其发布在 OpenRadar 上吗? :) @hhanesand 不,报告仍然打开,它是 rdar://17041392 但我没有将它添加到 OpenRadar。我敢打赌其他人已经在那里报道过,这个问题是两年前提出的。 ;) @Joey 意识到 :) ,但无论如何感谢,我想这是与 Apple 的错误报告者打交道时的预期结果。

以上是关于使用向后滑动手势以交互方式取消选择选定单元格的主要内容,如果未能解决你的问题,请参考以下文章

快速显示更多按钮时取消在表格视图单元格上向左滑动

滑动删除单元格不会取消 UIButton 操作

Obj-C - 展开选定的单元格,取消选中时折叠

为啥以编程方式选择单元格后 - 单元格不是交互?

只需一个手势滑动即可删除单元格

将手指放在其他单元格上时,选定的 tableViewCell 被取消选择