如何为集合视图单元格内的视图添加手势?

5

我正在添加一个视图,其中包含一组图片(socialView),放在集合视图单元格中(还有其他视图),需要执行一个共同的点击操作。这个点击操作不应该与集合视图单元格的点击相同。

我考虑每次在CollectionView委托方法cellForItemAt中为socialView添加UITapGestureRecognizer。但我想知道这样做是否正确?此外,我想获取调用socialView的indexPath/位置。

let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.socialViewTapped))

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "bidderAuctionCell", for: indexPath) as! BidderAuctionViewCell
     cell.socialView.addGestureRecognizer(tapGestureRecognizer)
}

@objc func socialViewTapped() {
     // Which item cell's socialview is clicked
}

更新

我已按以下建议操作,但我不知道在自定义单元格中应该添加UITapGestureRecognizer。以下是我创建的自定义单元格。

class CustomViewCell: UICollectionViewCell {

    var index : IndexPath!
    var socialViewDelegate : SocialViewDelegate!

    @IBOutlet weak var socialView: UIView!

    override init(frame: CGRect) {
        super.init(frame:frame)
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action:   #selector(self.viewTapped))
        socialView.addGestureRecognizer(tapGestureRecognizer)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder:aDecoder)
    }

    @objc func viewTapped(){
        socialViewDelegate.socialViewTapped(at: index)
    }
}

init函数没有被调用。我尝试了加入必要的init,但社交视图没有被初始化,导致崩溃。

最终答案

class CustomViewCell: UICollectionViewCell {

    var index : IndexPath!
    var socialViewDelegate : SocialViewDelegate!

    @IBOutlet weak var socialView: UIView!

    override func awakeFromNib() {
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap))
        socialView.isUserInteractionEnabled = true
        socialView.addGestureRecognizer(tapGesture)
    }

    @objc func handleTap(){
        socialViewDelegate.socialViewTapped(at: index)
    }
}
protocol SocialViewDelegate {
    func socialViewTapped(at index: IndexPath)
}

@RobertDresler 添加了代码,请检查。 - DevAnuragGarg
@JarvisTheAvenger 我已经更新了代码,但是我无法在自定义类中添加手势。 - DevAnuragGarg
你可以通过将indexPath传递给你的自定义类来解决这个问题,并将该点击委托给你的视图控制器。 - Jarvis The Avenger
你把这个类添加到单元格的XIB文件中了吗? - Jarvis The Avenger
你的自定义类中没有添加UIGestureRecognizerDelegate。 - Jarvis The Avenger
我已经更新了我的答案。你应该把所有与轻拍手势相关的内容放到awakeFromNib方法中。 - Jarvis The Avenger
3个回答

3

@Anurag,您可以通过使用委托、闭包或通知中的任何一个概念来解决此问题。我建议您采用委托模式,该模式在 iOS 中广泛应用于其组件,如 UITableView、UICollectionView 等。

  • 在实现委托模式之前,向视图添加一个轻拍手势识别器。
  • 在 CollectionViewCell 中声明一个协议方法以委托您的轻拍/操作。
  • 在您的视图控制器中确认委托实现。
  • 在您的视图控制器中实现您的委托方法。

编码示例:

1. 您的 CollectionViewCell 应如下所示:

   import UIKit

    Protocol ViewTappedDelegate: class {
     func viewTapped(_ photo : String) { }
   }

    class YourCell: UICollectionViewCell, UIGestureRecognizerDelegate {

        @IBOutlet weak var containerView: UIView!
        weak var delegate : ViewTappedDelegate?

        override func awakeFromNib() {
            let tapGesture = UITapGestureRecognizer(target: self,
                                                    action: #selector(handleTap(recognizer:)))
            tapGesture.delegate = self
            containerView.isUserInteractionEnabled = true
            containerView.addGestureRecognizer(tapGesture)
        }

        @objc func handleTap(recognizer:UITapGestureRecognizer) {
            //Call Delegate method from here...
        }

    }

2. 在 ViewController 中

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


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

              cell.delegate = self
              return cell
          }



    // MARK: Delegate
     extension YourViewController : ViewTappedDelegate {
        func viewTapped(_ photo : String) {
          // Handle delegation here...
        }
    }

嘿,谢谢,它起作用了。但您不需要添加tapGesture.delegate = self。只是我必须在awakeFromNib中编写代码。非常感谢。 - DevAnuragGarg

1
我希望如果你还没有找到方法,这个可以起作用。在自定义单元格中像这样使用协议。
import UIKit

protocol CustomDelegate {
    func showData(indexPath: IndexPath?)
}

class CustomCell: UICollectionViewCell {

// properties

var delegate: CustomDelegate?
var selectedAtIndex: IndexPath?

// outlets

override func awakeFromNib() {
    super.awakeFromNib()
    myView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(dothis)))
}

@objc func dothis(){
    delegate?.showData(indexPath: selectedAtIndex)
}

@IBOutlet weak var myView: UIView!
}

像这样编写您的视图控制器

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, CustomDelegate{
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CustomCell
    cell.delegate = self
    cell.selectedAtIndex = indexPath
    return cell
}
func showData(indexPath: IndexPath?) {
    if let ip = indexPath{
            print("\(ip) is the index path for tapped view")
    }
}
}

请告诉我这是否有帮助。

0
为了添加轻拍手势,请将以下代码添加到您的集合视图单元格中。
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.socialViewTapped))
socialView?.addGestureRecognizer(tapGestureRecognizer)
socialView?.isUserInteractionEnabled = true

将此代码添加到集合视图单元格中。

这是任何视图的通用解决方案,您能告诉我如何获取被点击的社交视图的indexPath.row吗?我已经添加了代码。 - DevAnuragGarg
基本思路是将此代码添加到您创建的单元格类中,因此将有一个不同的单元格对象。如果您想要indexPath,可以在单元格中创建一个变量,并在cellForRow at方法中设置它。 - Let's_Create
你现在可以检查一下吗?@Let's_Create - DevAnuragGarg
覆盖您的单元格类中的awakeFromNib方法,并在其中添加tap手势。 - Let's_Create

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接