在存在 UITapGestureRecognizer 的情况下选择 UICollectionViewCell

Posted

技术标签:

【中文标题】在存在 UITapGestureRecognizer 的情况下选择 UICollectionViewCell【英文标题】:Selecting UICollectionViewCell in the presence of UITapGestureRecognizer 【发布时间】:2018-04-16 18:17:53 【问题描述】:

我正在尝试回复UICollectionViewCell 选择:

private func setupCellAction() 
    collectionView?.rx.itemSelected
        .asObservable()
        .subscribe(onNext:  [weak self] indexPath in
            print("itemSelected!")
            let cell = self?.collectionView?.cellForItem(at: indexPath) as? CellTypeCollectionViewCell
            self?.performSegue(withIdentifier: "showBarchartSegue", sender: cell)
        ).disposed(by: disposeBag)

但不知何故,onNext 方法永远不会被调用。我尝试将setupCellAction() 放入viewDidLoadviewWillAppearviewDidAppear,但它不起作用。任何建议将不胜感激。

更新

我尝试了以下线程的建议:How to select CollectionView cell in RxSwift

并在subscribe 方法之前添加了.debug("RX: Model selected")。我在控制台中看到订阅了一次的输出。

更新

我尝试用以下方式重写setupCellAction()

private func setupCellAction() 
    collectionView?.rx.modelSelected(CellTypeCollectionViewCell.self)
        .asObservable()
        .debug("RX: Model selected")
        .subscribe(onNext:  [weak self] cell in
            print("itemSelected!")
            self?.performSegue(withIdentifier: "showBarchartSegue", sender: cell)
        ).disposed(by: disposeBag)

它也不起作用。我还看到它在控制台中订阅了一次。

更新

UICollectionViewController 被嵌入到另一个容器UIViewController 中,我在其中定义了UITapGestureRecognizer。注释掉UITapGestureRecognizer 的代码后,itemSelected() 方法开始起作用。现在我需要一种方法来让点击事件发生在UICollectionViewCell 上。有没有办法做到这一点?

容器控制器中点击的代码(viewDidLoad):

let tap = UITapGestureRecognizer(target: self, action: 
#selector(self.handleTap(_:)))
    tap.delegate = self
    view.addGestureRecognizer(tap)

handleTap():

@objc func handleTap(_ sender: UITapGestureRecognizer) 
    tableView.isHidden = true
    searchBar.resignFirstResponder()

【问题讨论】:

你什么时候设置代理的? 不确定您的意思,哪个代表? 我不确定。如果您设置委托,它可能会覆盖 itemSelected 事件。 使用 GestureRecognizer 即可。所以,当用户点击单元格时,我需要一种方法来避免这种情况,而不是其他任何地方 【参考方案1】:

您可以使用 UIGestureRecognizerDelegate 协议让点击通过并实现该方法 func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool.

基本上,如果我正确理解问题,您需要在触摸UICollectionViewCell 时返回false

您可以使用 UICollectionView 中的 func indexPathForItem(at point: CGPoint) -> IndexPath? 方法来执行此操作。如果给定的 CGPoint 与单元格的位置匹配,您将获得其 IndexPath。

不要忘记将触摸位置转换为集合视图的框架 - 您可以为此使用 UITouch 的 func location(in view: UIView?) -> CGPoint

它可能看起来有点像这样:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool 
    let point = touch.location(in: collectionView)
    return collectionView.indexPathForItem(at: point) == nil

【讨论】:

以上是关于在存在 UITapGestureRecognizer 的情况下选择 UICollectionViewCell的主要内容,如果未能解决你的问题,请参考以下文章

PHP会话变量在不应该存在的时候存在,在应该存在的时候不存在

SQL语句 存在就更新不存在就插入

文件在 Go 中既存在又不存在?

在jquery中怎么判断是不是存在

检查模板中是不是存在变量,如果不存在则不会在记录器中导致错误

在 c# 中,如何测试/获取/设置可能存在或不存在的注册表项?