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

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

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

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

【问题讨论】:

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

标签: ios uitableview uicollectionview


【解决方案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 的错误报告者打交道时的预期结果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-22
    • 2011-04-27
    • 2017-10-18
    相关资源
    最近更新 更多