代码之家  ›  专栏  ›  技术社区  ›  Extragorey

从UICollectionViewCell传播自定义事件

  •  4
  • Extragorey  · 技术社区  · 8 年前

    伪代码:

    class MyCell : UICollectionViewCell {
        @IBAction func myButton_touchUpInside(_ sender: UIButton) {
            // Do stuff, then propagate an event to the UICollectionView
            Event.fire("cellUpdated")
        }
    }
    
    class MyViewController : UIViewController {
        @IBAction func collectionView_cellUpdated(_ sender: UICollectionView) {
            // Update stuff in the view controller 
            // to reflect changes made in the collection view
        }
    }
    

    理想情况下,我定义的事件将出现在界面生成器中的默认操作出口旁边,允许我将其拖动到视图控制器代码中以创建上述内容 collectionView_cellUpdated @IBInspectable 用于公开自定义属性。

    有没有办法在本机Swift 3中实现这样的模式?或者,如果没有,有什么图书馆可以做到这一点?

    2 回复  |  直到 8 年前
        1
  •  3
  •   PGDev    8 年前

    我不完全理解你的问题,但从我得到的情况来看,你可以简单地使用 closure UIButton 将事件点击回 UIViewController .

    1、自定义 UICollectionViewCell

    class MyCell: UICollectionViewCell
    {
        var tapHandler: (()->())?
    
        @IBAction func myButton_touchUpInside(_ sender: UIButton)
        {
            tapHandler?()
        }
    }
    

    2. MyViewController

    class MyViewController: UIViewController, UICollectionViewDataSource
    {
        //YOUR CODE..
    
        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
        {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! MyCell
            cell.tapHandler = {
                //Here you can do your custom handling
            }
            return cell
        }
    }
    

    如果你面临任何问题,请告诉我。

        2
  •  2
  •   jlmurph    8 年前

    最好的做法是为您的自定义单元类创建一个自定义协议

    protocol CustomCellProtocolDelegate {
       func custom(cell: YourCellClass, hadButton: UIButton, pressedWithInfo : [String:Any]?)
    }
    

    class YourCellClass: UICollectionViewCell {
    
       var delegate : CustomCellProtocolDelegate?
    
       var indexPath : IndexPath? //Good practice here to have an indexPath parameter
    
       var yourButton = UIButton()
    
       init(frame: CGRect) {
          super.init(frame: frame)
          yourButton.addTarget(self, selector: #selector(triggerButton(sender:)))
       }
       func triggerButton(sender: UIButton) {
          if let d = self.delegate {
             d.custom(cell: self, hadButton: sender, pressedWithInfo : /*Add info if you want*/)
          }
       }
    
    }
    

    在控制器中,将其与委托相一致,并将委托应用于 cellForItem: atIndexPath :

    class YourControllerThatHasTheCollectionView : UIViewController, CustomCellProtocolDelegate {
    
        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "identifier", for: indexPath) as! YourCellClass
            cell.delegate = self
            cell.indexPath = indexPath
            return cell
        }
    
       func custom(cell: YourCellClass, hadButton: UIButton, pressedWithInfo : [String:Any]?) {
    
            //Here you can process which button was selected, etc.. and apply your changes to your collectionview
    
       }
    
    }
    

    最佳做法是在 pressedWithInfo indexPath

        protocol CustomCellProtocolDelegate {
           func custom(cell: YourCellClass, hadButton: UIButton, pressedAt: IndexPath, withInfo : [String:Any]?)
        }
    
        func triggerButton(sender: UIButton) {
           if let d = self.delegate {
               d.custom(cell: self, hadButton: sender, pressedAt: indexPath!, withInfo : /*Add info if you want*/)
           }
        }