集合视图单元格按钮不触发操作

时间:2016-12-06 06:20:04

标签: swift xcode uibutton uicollectionview uicollectionviewcell

所以我在集合视图单元格xib中有一个看起来像铅笔的按钮。

enter image description here

然后我有了这段代码。

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "groupsCollectionViewCellIdentifier", for: indexPath) as! GroupCollectionViewCell

    //add action to the edit button
    cell.editButton.tag = indexPath.row
    cell.editButton.addTarget(self, action: #selector(GroupsCollectionViewController.editGroupAction), for: .touchUpInside)

    return cell
}

//segue to edit group
func editGroupAction() {
    performSegue(withIdentifier: "editGroupSegue", sender: self)
}

但每当我点击编辑按钮。什么都没发生。我想知道什么是失踪的。

10 个答案:

答案 0 :(得分:1)

考虑到您的问题,我创建了一个演示,其中包含您在上面提供的详细信息以及一些细微的更改 我修改了您的onChange(event, value){ if(event.keyCode == 13){ //put the logic here } 方法。我的修改版本如下。

cellForItem


动作方法如下:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell : GroupCollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "groupsCollectionViewCellIdentifier", for: indexPath) as! GroupCollectionViewCell


    cell.editButton.tag = indexPath.row
    cell.editButton.addTarget(self, action: #selector(editGroupAction(sender:)), for: .touchUpInside)

    return cell
}


从您的代码我修改了以下细节:
1)func editGroupAction(sender: UIButton) { print("Button \(sender.tag) Clicked") } 对象的声明方式 2)为UIButton分配UICollectionViewCell方法的方法。到最后一刻 3)在动作方法中,我打印了Button标签。

通过上述修改,我得到了正确的结果。我将选定的索引值作为按钮标记,在consol中的代码中指定。我得到的输出如下。

#Selector

我希望这可以满足您的要求。

答案 1 :(得分:1)

在您的手机上尝试这个

self.contentView.isUserInteractionEnabled = false

答案 2 :(得分:1)

我遇到了同样的问题,并且在使用View层次结构之后,我注意到向该单元格添加了另外的UIView。 该视图位于我的UIButton上方,因此触摸事件没有传递到按钮,而是触发了didSelectItem

我通过以下调用解决了这个问题:

cell.bringSubviewToFront(cell.button)

现在将调用该事件。

答案 3 :(得分:1)

要在Custom UICollectionCell的UIButton上启用触摸操作,请在Custom UICollectionCell类中添加以下方法。

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    var view = myButton.hitTest(myButton.convert(point, from: self), with: event)
    if view == nil {
        view = super.hitTest(point, with: event)
    }

    return view
}

答案 4 :(得分:0)

您是将类分配给单元格并将该按钮与控制器链接,并将标识符分配给segue,还使用断点来检查func是否被调用

并使用像这样的segue

func editGroupAction() {
    performSegue(withIdentifier: "editGroupSegue", sender: self)
    let src = self.sourceViewController as UIViewController
    let dst = self.destinationViewController as UIViewController
    src.navigationController.pushViewController(dst, animated:false)
}

答案 5 :(得分:0)

如果您使用的是iOS 10.以下是工作代码

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell


           let cell = collectionView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! YourCellClass
 cell.btnJoin.tag = (indexPath as NSIndexPath).row    
 cell.btnJoin.addTarget(self, action: #selector(YourViewControllerClassName.doSomething(_:)), for: UIControlEvents.touchUpInside)
    }

动作

 func doSomething(_ sender: UIButton)  {
          print("sender index",sender.tag)
   }

答案 6 :(得分:0)

我花了数小时在网上搜寻有关UIButton内部UICollectionView无法正常工作的解决方案。让我发疯,直到我终于找到了适合我的解决方案。而且我相信这也是正确的方法:破解热门测试。与解决UICollectionView Button问题相比,此解决方案可以更深入(双关语意),因为它可以帮助您将click事件传递到掩藏在阻止事件通过的其他视图下的任何按钮:

UIButton in cell in collection view not receiving touch up inside event

由于SO答案在目标C中,所以我从那里的线索中找到了快速解决方案:

http://khanlou.com/2018/09/hacking-hit-tests/

-

当我要禁用单元格上的用户交互或尝试的其他任何答案时,没有任何效果。

我上面发布的解决方案的美丽之处在于,您可以按照自己的习惯保留addTarget和选择器函数的功能,因为它们最有可能永远不会成为问题。您只需要重写一个功能即可帮助触摸事件到达目的地。

解决方案为何起作用:

在开始的几个小时里,我发现我的addTarget调用未正确记录该手势。事实证明,目标注册良好。触摸事件根本无法到达我的按钮。

现实似乎是从我读过的许多SO帖子和文章中得知,UICollectionView单元旨在容纳一个动作,由于各种原因而不是多个。因此,仅应该使用内置的选择操作。考虑到这一点,我相信绕过此限制的正确方法不是破解UICollectionView来禁用滚动或用户交互的某些方面。 UICollectionView仅在执行其工作。 正确的方法是破解点击测试,以在点击进入UICollectionView之前拦截该点击,并弄清他们正在点击哪些项目。然后,您只需将触摸事件发送到他们所点击的按钮,然后让您的普通东西完成工作即可。


我的最终解决方案(来自khanlou.com文章)是将我的addTarget声明和选择器函数放在我喜欢的任何位置(在单元类或cellForItemAt中),并在单元类中覆盖hitTest函数。

在我的细胞班里,我有:

@objc func didTapMyButton(sender:UIButton!) {
    print("Tapped it!")
}

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {

    guard isUserInteractionEnabled else { return nil }

    guard !isHidden else { return nil }

    guard alpha >= 0.01 else { return nil }

    guard self.point(inside: point, with: event) else { return nil }


    // add one of these blocks for each button in our collection view cell we want to actually work
    if self.myButton.point(inside: convert(point, to: myButton), with: event) {
        return self.myButton
    }

    return super.hitTest(point, with: event)
}

在单元格初始化中,我有:

self.myButton.addTarget(self, action: #selector(didTapMyButton), for: .touchUpInside)

答案 7 :(得分:0)

我意识到这张票已经很旧了,但我遇到了同样的问题,并找到了不同的解决方案。

我使用视图调试器运行 Xcode。虽然按钮的大小正确,但它的超级视图的宽度为 0 点。这将导致无法点击此按钮或任何其他子视图。

只是提一下,因为它可能值得一试。

答案 8 :(得分:0)

顺便说一下,我必须实施命中测试解决方案,然后我在下面遇到了这个问题:

我遇到了类似的问题,我的一个按钮可以正常工作,而单元格底部的另一个按钮无法正常工作,并且它位于堆栈视图内。因此,经过数小时环顾四周,我发现其中一个父视图(在按钮和 CollectionView 本身之间)的大小小于其子视图的大小,在这种情况下,根本没有报告触摸,因为它们是发生在父视图之外......修复了这个问题,它就像一个魅力......

更具体地说,我为我的集合视图和名为“_UICollectionViewOrthogonalScrollerEmbeddedScrollView”的视图使用了一个组合布局,它是集合视图单元格的包装器,估计大小小于它自己的单元格

答案 9 :(得分:0)

如果您以编程方式声明按钮,则需要确保将它们设置为 lazy var 对象


class myCell: UICollectionViewCell {

  static let identifier = "myCellId"

  lazy var myButton: UIButton = {
    let btn = UIButton()
    btn.addTarget(self, action: #selector(handleButtonPress(_:)), for .touchUpInside)
    return btn
  }()

  // rest of cell 

}