

こんにちは。  
つかぬ事をお聞きしてしまうのですが、protocolの実装について方法が分からなくて困っています。  
どなたか回答いただけたら幸いです。

* * *

1つのViewControllerにcontainerViewなどの都合で複数のViewControllerをプロパティで持たせていて(viewControllersという配列)その複数のViewControllerにはtableViewを必ず1つ持たせようと思います。

[code]

    override func setEditing(_ editing: Bool, animated: Bool) {
        super.setEditing(editing, animated: animated)
        if let firstVC = viewControllers[currentIndex] as? FirstViewController {
            firstVC.tableView.isEditing = editing
        }
        if let secondVC = viewControllers[currentIndex] as? SecondViewController {
            secondVC.tableView.isEditing = editing
        }
        if let thirdVC = viewControllers[currentIndex] as? ThirdViewController {
            thirdVC.tableView.isEditing = editing
        }
    }
    
[/code]

このように1つ1つダウンキャストして判定するのも良いのですが少し単調な気がします。

配列の中のViewController達の親としてtableViewを持つようなUIViewControllerクラスが欲しいところなのですが  
Swift言語でプロトコルを用いて良い感じに実装するにはどのようにすれば良いでしょうか...?


CC BY-SA 3.0
2017-02-04T13:35:01.930
32386
2020-09-04T04:04:10.567
2019-06-13T11:04:46.620
19110
19269
question
swift swift3
Swiftのプロトコル準拠について(Javaなどの未詳細クラスなど)


「良い感じ」になっているかどうかは、かなり怪しい気がしますが、「Swift言語でプロトコルを用いて」と言う部分だけを取らせてもらうと、こんな感じになるでしょうか。

[code]

    protocol HavingTableView {
        var tableView: UITableView! {get}
    }
    extension FirstViewController: HavingTableView {}
    extension SecondViewController: HavingTableView {}
    extension ThirdViewController: HavingTableView {}
    
    //...
        override func setEditing(_ editing: Bool, animated: Bool) {
            super.setEditing(editing, animated: animated)
            if let tableViewVC = viewControllers[currentIndex] as? HavingTableView {
                tableViewVC.tableView.isEditing = editing
            }
        }
    
[/code]

現在のSwiftではクラスとプロトコルを組み合わせて、`UIViewController &
HavingTableView`のようなデータ型を作ることができないので、`viewControllers`は`[UIViewController]`としておく想定です。そうすると`as?
HavingTableView`のようなキャストも必要になるし、あまり「良い感じ」には見えないかもしれません。

* * *

「配列の中のViewController達の親としてtableViewを持つようなUIViewControllerクラスが欲しい」と言うのであれば、そのままそれを共通の親クラスとして定義してしまうという手もありますが。

[code]

    class MyBaseViewController: UIViewController {
        var tableView: UITableView!
    }
    class FirstViewController: MyBaseViewController {
        //...
    }
    class SecondViewController: MyBaseViewController {
        //...
    }
    class ThirdViewController: MyBaseViewController {
        //...
    }
    
    //...        
        var viewControllers: [MyBaseViewController] = []
    
        override func setEditing(_ editing: Bool, animated: Bool) {
            super.setEditing(editing, animated: animated)
            viewControllers[currentIndex].tableView.isEditing = editing
        }
    
[/code]

私的にはこちらの方が「良い感じ」に思えるのですが、`tableView`を`@IBOutlet`にしたいのなら、ちょっと面倒かもしれません。


CC BY-SA 3.0
2017-02-04T14:10:37.830
32388
2017-02-04T14:10:37.830
13972
32386
answer