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

Posted

技术标签:

【中文标题】如何为集合视图单元格内的视图添加手势?【英文标题】:How to add gesture for a view inside a collection view cell? 【发布时间】:2019-01-14 07:04:25 【问题描述】:

我在一个集合视图单元(也有其他视图)内添加了一个具有images(socialView) 集合的视图,必须对其执行常见的点击。此单击不应与集合视图单元格单击相同。

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

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 函数没有被调用。我也尝试放入所需的初始化,但社交视图未初始化。所以崩溃了

最终答案

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 添加了代码。请检查 @JarvisTheAvenger 我已经更新了代码,我无法在自定义类中添加手势 您可以通过将 indexPath 传递给您的自定义类来解决它。并将点击委托给您的视图控制器 你有没有把这个类添加到cell的XIB中?? 您尚未将 UIGestureRecognizerDelegate 添加到您的自定义类中 【参考方案1】:

@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 中编写代码。非常感谢。【参考方案2】:

如果你还没有找到方法,我希望这能奏效 您在这样的自定义单元格中使用这样的协议

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")
    


请告诉我这是否有帮助

【讨论】:

【参考方案3】:

要添加点击手势,请将以下代码添加到您的收藏视图的单元格中。

let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.socialViewTapped))
socialView?.addGestureRecognizer(tapGestureRecognizer)
socialView?.isUserInteractionEnabled = true

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

【讨论】:

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

以上是关于如何为集合视图单元格内的视图添加手势?的主要内容,如果未能解决你的问题,请参考以下文章

将数据从集合视图单元格内的表视图单元格传输到另一个集合视图单元格 [带图片!]

集合视图单元格的自动布局行为怪异

如何从表格视图单元格中的图像手势获取 indexPath

如何在表格视图单元格内创建集合视图

在表格视图中的所有单元格都已加载后,重新加载表格视图单元格内的集合视图

如何为用户输入文本时将动态创建的每个单元格设置按钮操作(Swift 4)?