如何避免委托调用的痕迹

问题描述 投票:2回答:3

我有一个UIViewController有一个UICollectionView,里面我有一个控制ListSectionControllerUICollectionViewCell类,在那个单元格里面我有一个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

这看起来像是很多代码重复而且有点浪费空间。我怎样才能改善这一点?

ios swift swift-protocols
3个回答
1
投票

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

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

例如,我们为按钮提供了一个无目标的操作:

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

在视图控制器中我们有:

    @objc func buttonPressed(_ sender: Any) {

这将起作用,因为视图控制器位于响应器链的按钮上方。这正是针对零目标的行为。


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


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

0
投票

我已经遇到过很多次这种情况因此我想首先明确说明:

“如果您的单元格(以及其中的视图)负责执行一个且仅执行一个操作(可能是其中的表单按钮)”,则可以使用didSelectItemAtIndexPath“。通过使用UIImageView设计视图。此方法存在一些UX问题例如,突出显示,除了那些之外,还可以使用委托处理。

如果情况并非如此,并且您的单元格正在执行多个操作,则Mat的答案会给出最佳方法。

© www.soinside.com 2019 - 2024. All rights reserved.