iOS Swift,协议中有一个常用方法,两个ViewControllers中有两个实现,如何决定调用哪个ViewControllers方法?

时间:2018-03-26 17:04:18

标签: ios swift uiviewcontroller delegates

我有一个协议

protocol HandleEmbedController: class {
    func printMsg()
}

和2个容器视图和2个相应的ViewControllers

class EnemyBaseVC: UIViewController, HandleEmbedController {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    var value1 = ""

    func printMsg(){
        print("printing some embedded message")
    }

} 

class EnemyBase2VC: UIViewController, HandleEmbedController {

    func printMsg() {
        print("enemy base 2 message")
    }

    override func viewDidLoad() {
        super.viewDidLoad()

    }

}

并且都使用协议HandleEmbedController并实现printMsg函数。

在ViewController中我有

class HomeBaseVC: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    var handleEmbedController:HandleEmbedController?

    @IBAction func onclick(_ sender: UIButton) {

        handleEmbedController?.printMsg()
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

        if (segue.identifier == "embedseg"){
            if let embed = segue.destination as? EnemyBaseVC     {
                self.handleEmbedController = embed
            }
        }

        if (segue.identifier == "embedseg2"){
            if let embed = segue.destination as? EnemyBase2VC     {
                self.handleEmbedController = embed
            }
        }


    }
}

单击按钮时,始终调用EnemyBaseVC方法并打印

printing some embedded message

有没有办法决定调用哪个方法?

更新 Main storyboard layout

1 个答案:

答案 0 :(得分:0)

如果你有两个容器视图,那么两个segue都会在加载时被触发,而handleEmbedController将引用最后加载的一个ViewController。

如果您有一些逻辑来决定应该引用哪一个,那么您可以使用它来决定引用哪个ViewController,如下所示:

class HomeBaseVC: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()

}

var handleEmbedController:HandleEmbedController?

//  comes from your decision logic
var decisionMaker: Bool = false

@IBAction func onclick(_ sender: UIButton) {

    handleEmbedController?.printMsg()
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

    if (segue.identifier == "embedseg"),
        let embed = segue.destination as? EnemyBaseVC,
        decisionMaker {
        self.handleEmbedController = embed
    }

    else if (segue.identifier == "embedseg2"),
        let embed = segue.destination as? EnemyBase2VC,
        !decisionMaker {
        self.handleEmbedController = embed
    }
  }
}

请注意,这将在加载时设置handleEmbedController,如果您需要更复杂的行为,您可以处理handleImbedController在segue之外的其他地方的分配。

由于这是您的基本ViewController必须与多个对象通信的场景,您还可以使用通知而不是委托。这样,您可以决定在用户​​点按按钮时要发送哪条消息。您的基本ViewController看起来像这样

class HomeBaseVC: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    //  comes from your decision logic
    var decisionMaker: Bool = true

    @IBAction func onclick(_ sender: UIButton) {
        NotificationCenter.default.post(name: NSNotification.Name(rawValue: "BUTTON_WAS_TAPPED"), object: nil, userInfo: ["decision" : decisionMaker])
    }
}

而敌人的ViewControllers看起来像这样(第二个除了要处理的决策值之外会相同)

class EnemyBaseVC: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "BUTTON_WAS_TAPPED"),
                                           object: nil,
                                           queue: nil) { notification in
                                                if let userInfo = notification.userInfo,
                                                    let decision = userInfo["decision"] as? Bool,
                                                    decision {
                                                        self.printMsg()
                                                }
        }
    }

    var value1 = ""

    private func printMsg(){
        print("printing some embedded message")
    }
}