LoginSignup
13
15

More than 5 years have passed since last update.

ProtocolExtensionを利用して画面遷移拡張プロトコルの基底処理を実装してみたサンプル

Last updated at Posted at 2016-01-24

概要

ProtocolExtensionの学習がでらに画面遷移時にパラメータを渡すような処理を実装してみたサンプルです。

アイデア自体はObjCで上司が書いた画面遷移カテゴリを参考にしています。

ProtocolExtensionについて

プロトコルに基底の処理を実装できるSwiftの機能です。APIKitなどのライブラリで型制約したリクエストをつくる際に利用方法されていたりします。

まずはProtocolの実装

ViewControllerから呼び出して遷移するためのメソッド showViewController<T:RoutingProtocol>を追加してRoutingProtocolに準拠したViewControllerと、コメントで頂きましたParam型のパラメータしか利用できないよう制約をつけています。

setupWithParamsはパラメータを受け取るためのメソッドです。


protocol RoutingProtocol{

    typealias Param = AnyObject

    /**
     pushViewcontroller with any argument

     - parameter viewController: conform to RoutingProtocol
     - parameter params:        any argument
     */
    func showViewController<T:RoutingProtocol>(viewController:T, params:T.Param?)

    /**
     By overridden by viewController conforming to RoutingProtocol,
     and receives parameters from the transition source

     - parameter params: any arugument
     */
    func setupWithParams(params:Param?)
}

つづいてProtocolExtension

基底の処理を実装します。

extension RoutingProtocol where Self: UIViewController{

    func setupWithParams(params:Param?) {}

    func showViewController<T:RoutingProtocol>(viewController:T, params:T.Param?){
        viewController.setupWithParams(params)
        guard let vc = viewController as? UIViewController else{
            print("cast failure")
            return
        }
        self.navigationController?.pushViewController(vc, animated: true)
    }
}

ポイント1

setupWithParamsはプロトコルに準拠したViewControllerがオーバーライドしたときのみパラメータを受け取れるように中身を空で実装しています。引数を受け取る必要のないViewController等は実装の手間が省けます。

ポイント2

func showViewController<T:RoutingProtocol>(viewController:T, params:Param?)で型制約を行うことでRoutingProtocolに準拠したViewControllerと引数を受け取ってsetupWithParamsメソッドを呼び出し、パラメータを渡すことができます。

今回は実装してませんがnavigationControllerを持っている前提の遷移処理になっていますので無い場合は追加するなり、モーダルにするなりの対応が必要ですかね。

利用方法

遷移元は勿論、遷移先であるDetailViewController()もRoutingProtocolに準拠していることがshowViewControllerメソッド呼び出し時に求められます。渡すパラメータは DetailViewControllerで指定しているStringでないと怒られます。

class ViewController: UIViewController, RoutingProtocol {

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    @IBAction func showDetailDidTap(sender: UIButton) {
        self.showViewController(DetailViewController(), params:"anything")
    }
}

遷移先

Param型の指定を行うことで setupWithParamsで受け取りたいパラメータの型制約をしています。

class DetailViewController: UIViewController, RoutingProtocol{

    // parameter type Constraints
    typealias Param = String

    // MARK: override

    func setupWithParams(params: Param?) {
        print("\(params!)")
    }

}

プロジェクトファイルはこちら

参考にさせて頂きました。ありがとうございます。

13
15
3

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
13
15