【问题标题】:How to write a swift function that returns one of three types?如何编写一个返回三种类型之一的快速函数?
【发布时间】:2020-04-02 21:13:11
【问题描述】:

我有三个视图控制器WebkitViewController,然后是另外两个视图控制器WebkitViewControllerAWebkitViewControllerB,它们都扩展了WebkitViewController。我在编写一个通用函数时遇到了麻烦,该函数将查看 segue 目的地的视图控制器并告诉我它是三种类型中的哪一种。有没有更好的方法来做到这一点?

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.destination is WebKitViewController && sender is UIButton {
            let viewControllerType = {
                if segue.destination is WebKitViewControllerA {
                    WebKitViewControllerA.self
                } else if segue.destination is WebKitViewControllerB {
                    WebKitViewControllerB.self
                } else {
                    WebKitViewController.self
                }
            }()

            let button = sender as? UIButton
            let vc = segue.destination as? viewControllerType
            vc?.foo = "ho ho ho"
        }

    }

}

我还尝试了类似以下的方法:

    var vc: WHAT_TYPE_TO_PUT_HERE?
    if segue.destination is CustomViewController {
        vc = segue.destination as? CustomViewController
    } else if segue.destination is WebKitBelowFoldViewController {
        vc = segue.destination as? WebKitBelowFoldViewController
    } else {
       vc = segue.destination as? WebKitViewController
    }

但我不知道我可以给 vc 什么类型的类型检查器会满足。

【问题讨论】:

  • segues 的标识符不是唯一的,因此更容易检查标识符吗?
  • @vadian 如果您要依赖类型(通过as?)来分配某些属性,那么您不妨依赖类型而不是还需要标识符。
  • 三个VC类有关系吗? WebKitViewControllerAWebKitViewControllerBWebKitViewController 的子类吗?

标签: swift types


【解决方案1】:

不要试图摆弄具体的类型,而是创建一个所有三个 VC 都符合的协议。

看起来这三个 VC 的共同点是它们都有一个foo 属性,所以我们可以这样创建一个协议:

protocol HasFoo { // you should give this a better name base on your actual situation
    var foo: String! { get set } // remember to match the type of the foo property
}

然后让三个 VC 都符合它:

extension WebKitViewController : HasFoo {

}

extension WebKitViewControllerA : HasFoo {

}

extension WebKitViewControllerB : HasFoo {

}

现在您可以在prepareForSegue 中简单地执行此操作:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let vc = sender.destination as? HasFoo {
        vc.foo = "ho ho ho"
    }
}

【讨论】:

    【解决方案2】:

    由于这些都是 WebkitViewController 的子类,vc 将是 WebkitViewController。此外,鉴于您在此处显示的代码,应该没有理由检查每种类型。您只需要:

    if let vc = segue.destination as? WebKitViewController {
        vc.foo = "ho ho ho"
    }
    

    【讨论】:

    • 哇,非常感谢 - 我让这变得不必要地复杂了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多