2

我有一个UIViewController,其中有一个UICollectionView,里面我有一个ListSectionController控制 a 的类,UICollectionViewCell在那个单元格里面我有一个UIView子类。

当按下按钮时,我需要从UIViewController. 目前我有一系列委托方法,因为它可以像这样回到视图控制器:

class MyView {
    // delegate is the cell that the view is contained in

    @IBAction func buttonPress() {
        delegate?.myDelegateMethod()
    }
}

extension MyCell : MyViewDelegate {
    // The delegate is the section controller

    func myDelegateMethod() {
        delegate?.myDelegateMethod()
    }
}

... etc

这似乎有很多代码重复,有点浪费空间。我该如何改进呢?

4

3 回答 3

1

当按下按钮时,我需要从 UIViewController 调用一个方法

一种方法:给按钮一个以nil 为目标的动作,并在 UIViewController 中实现动作方法。消息将自动到达。

例如,我们给按钮一个以 nil 为目标的动作:

    class Dummy {
        @objc func buttonPressed(_:Any) {}
    }
    button.addTarget(nil,
        action: #selector(Dummy.buttonPressed),
        for: .touchUpInside)

在视图控制器中,我们有:

    @objc func buttonPressed(_ sender: Any) {

这将起作用,因为视图控制器位于按钮的响应者链上。这正是 nil-targeted 操作的用途。


另一种方法是使用 NotificationCenter 和 Notification。我认为这在这种情况下也非常合适。

于 2019-03-15T16:07:34.247 回答
0

您可以以一种通用的、类型安全的方式直接将响应者链向上到达任何父视图或视图控制器:

extension UIResponder {
    func firstParent<T: UIResponder>(ofType type: T.Type ) -> T? {
        return next as? T ?? next.flatMap { $0.firstParent(ofType: type) }
    }
}
guard let ListSectionController = firstParent(ofType: ListSectionController) else {
 return // we aren't in a ListSectionController
}
//Call ListSectionController methods here
于 2019-03-15T15:39:05.223 回答
0

我遇到这种情况很多次,因此我想先声明一下:

“如果您的单元格(以及其中的视图)负责执行一个且仅一个操作(可能是其中的表单按钮)”,您可以使用didSelectItemAtIndexPath“。通过使用 设计您的视图UIImageView。这种方法有一些用户体验问题,例如, highlight 以及除这些之外的所有内容也可以使用委托处理。

如果不是这种情况,并且您的单元格正在执行多个操作 Mat 的答案给出了最佳方法。

于 2019-03-16T05:39:49.037 回答