

VIewControllerにTestViewControllerのデリゲート(myDelegate)を設定する際に、  
VIewDataのgetViewControllerメソッドを仲介する形式で実現させたいのですが  
下記ソースの通り、ViewControllerの `topController.myDelegate = self` でビルドエラーとなります。

デリゲートの使い方が間違っているのでしょうか？そもそもメソッド(getViewController)で  
デリゲートを渡す方法はできないのでしょうか？

**VIewController.swift**

[code]

    import UIKit
    
    class ViewController: UIViewController,myDelegate{
    //ビューデータ読み込み
        var viewdata = ViewData()
         override func viewDidLoad() {
            super.viewDidLoad()   
            var controllers:[UIViewController]=[]
            let topController = viewdata.getViewController("TEST")
            topController.myDelegate = self // ←ここでビルドエラー【Value of type 'UIViewController' has no member 'newsDelegate’】
            controllers.append(topController)   
            ~~~~~~
         }
        func myTest() {
                ~~~~~~
        }
    }
    
[/code]

**VIewData.swift**

[code]

    import UIKit
    class ViewData{
    
      func getViewController(_ text:String)->UIViewController{
        switch text{
          case “TEST”:
            let storyboard:UIStoryboard = UIStoryboard(name:"Main",bundle:nil)
            let TestView = storyboard.instantiateViewController(withIdentifier: "Test") as! TestViewController
            return TestView
    
          default:
        }
    
      }
    
    }
    
[/code]

**TestViewController.swift**

[code]

    import UIKit
    class TestViewController:UITableViewController{
        var myDelegate:myDelegate?
    
        override func viewDidLoad() {
                super.viewDidLoad()
            ~~~
        }
        ~~~
        func A(){
            myDelegate?.myTest()　// ここの実行結果をViewControllerで受けたい
        }
    }
    
[/code]

**myDelegate.swift**

[code]

    import UIKit
    protocol myDelegate{
      func myTest()
    }
    
[/code]


CC BY-SA 4.0
2019-12-27T01:29:29.463
61816
2019-12-29T04:05:09.160
2019-12-27T02:07:33.653
37089
37089
question
swift delegate
メソッドを経由してデリゲートを設定する方法


コメントに書かれているように、

`topController.myDelegate = self`

と言う文がコンパイルエラーにならないようにするためには、Swiftコンパイラーに`topController`のデータ型が`TestViewController`であるとわからせておかないといけません。

あなたの今のコードでは、`ViewData.getViewController(_:)`の戻り値は`UIViewController`とはっきり宣言しているのですから、Swiftは`topController`の型を`UIViewController`と認識します。

従って、前の行の`topController`の宣言をこんな風に変えてやる必要があるでしょう。

[code]

            let topController = viewdata.getViewController("TEST") as! TestViewController
    
[/code]

Swiftの静的型付けのシステム(コンパイル時に型が決まる)において「TestViewController以外の型をcase文毎に返す」のは、「難しい」のではなく、
**不可能** です。

従って、`getViewController(_:)`の中で、`TestView`(別の話になりますが、ローカル変数は小文字スタートにすべきです)の宣言につけている`as!
TestViewController`には、あまり意味はありません。

* * *

正直言って、view
controllerをインスタンス化すると言う処理はアプリの中でそう何回も呼ばれる訳でもないため、(現在提示されているコードだけでは)`getViewController(_:)`なんてメソッドを別に定義することのメリットが何も感じられない状態になっています。

なぜswitch文で制御される`getViewController(_:)`のようなメソッドを作ろうと思われたのでしょうか?
そこら辺をご提示いただければ、また違う解決方法があるかもしれません。


CC BY-SA 4.0
2019-12-29T04:05:09.160
61870
2019-12-29T04:05:09.160
13972
61816
answer