LoginSignup
1
4

More than 5 years have passed since last update.

targetViewController(forAction:sender:)の使い方を考えてみた

Posted at

targetViewController(forAction:sender:)を利用する方法を考えてみました。

以下のアクションを実行できるViewControllerに委譲したいと考えます。

@objc protocol SomeProtocol:NSObjectProtocol {
    @objc func someAction(sender:Any?)
}

親のViewControllerが子としてUINavigationViewControllerとSomeProtocolを実装したViewControllerを持っているとします。

その時、targetViewController(forAction:sender:)を使えば階層をたどって実行できるViewControllerを手に入れることができます。


// 子のViewController
class ServiceViewController : UIViewController {

    @IBAction func pushed(sender:Any?) {

        // ViewController階層の先祖でアクションを実装している人にアクションができる人を探す。
        let t = self.targetViewController(forAction: #selector(SomeProtocol.someAction(sender:)), sender: sender)

        // アクションを委譲する。
        t?.perform(#selector(SomeProtocol.someAction(sender:)), with: sender)
    }
}

SomeProtocolを実装しているViewControllerは

class DetailViewController:UIViewController, SomeProtocol {

    @IBOutlet weak var label: UILabel!

    func someAction(sender: Any?) {
        label.text = "someAction done"
    }
}

 親のViewControllerはtargetViewController(forAction:sender:)を実装し、SomeProtocolを実装しているViewControllerを見つけて渡します。

// 複数のServiceViewControllerが入っているUINavigationViewControllerと
// DetailViewControllerをchildViewControllersにもつとする。
class ModalServiceParentController: UIViewController {

    // 特定のアクションを拾う
    override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
        if action == #selector(SomeProtocol.someAction(sender:)) {
            return true
        }

        return super.canPerformAction(action, withSender: sender)
    }

    // そのアクションを実行するViewControllerを渡す。
    override func targetViewController(forAction action: Selector, sender: Any?) -> UIViewController? {
        if action == #selector(SomeProtocol.someAction(sender:)) {
            let vc = self.childViewControllers.first {vc in vc is SomeProtocol}
            return vc
        }
        return super.targetViewController(forAction: action, sender: sender)
    }
}
1
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
4