swift 从情节串联图板转换为子类

afdcj2ne  于 2023-08-02  发布在  Swift
关注(0)|答案(3)|浏览(116)

假设我有一个BaseViewController。然后我有两个场景,新建和编辑,两者共享相同的UI和大部分逻辑。所以我创建了类NewViewController和EditViewController,子类BaseViewController。当我试图从故事板示例化“BaseViewController”时,问题来了,因为我想指定哪个实现是。

if isEdit { 
    storyboard.instantiateViewControllerWithIdentifier("baseVCIdentifier") as! EditViewController 
} else {
   storyboard.instantiateViewControllerWithIdentifier("baseVCIdentifier") as! NewViewController 
}

字符串
然后我得到一个错误:未能将类型“Test.BaseViewController”(0x10ee5e0f0)的值强制转换为“Test.EditViewController”(0x10ee5f000)。
我不想在故事板上同时拥有两个ViewController,因为我不想重做相同的UI 2次。

ukdjmx9f

ukdjmx9f1#

您可以使用instantiateViewController(identifier:creator:)来完成此操作。
我假设您在故事板中有视图控制器,标识符为template。故事板中分配给视图控制器的类应该是超类:

let storyboard = UIStoryboard(name: "main", bundle: nil)

let viewController = storyboard.instantiateViewController(identifier: "template") { coder in 
    // this passes us with a coder for the storyboard, we can now init the preferred subclass.

    if useSubclass {
        return SpecialViewController(coder: coder)
    } else {
        return BaseViewController(coder: coder)
    }
}

字符串
这里是documentation

wqlqzqxt

wqlqzqxt2#

就这么简单,只需要将withIdentifier改为identifier即可。

let v = UIStoryboard(name: "A", bundle: nil)
    .instantiateViewController(withIdentifier: "A")
present(v)

字符串
相反...

let v = UIStoryboard(name: "A", bundle: nil)
    .instantiateViewController(identifier: "A") { coder in
                                      return B(coder: coder) }
present(v)


就这么简单

  • (这与@JustinMeiners的回答是相同的概念,我向其发送了大量赏金,但为了清晰起见,这里的编码更简单。

一个方便的细节:
如果你这么做

let v = sb.instantiateViewController(withIdentifier: "A")
present(v)


事实上在现实中你必须这样做

let v = sb.instantiateViewController(withIdentifier: "A") as! A
present(v)


你必须把它转换成A**,这样你才能真正使用变量v.yourStuff = 69等。
所以我们都打了“as!废话”一百万次。
但是,当您使用“identifier”而不是“withIdentifier”时,

let v = sb.instantiateViewController(identifier: "A") { coder in
                                            return B(coder: coder) }
present(v)


事实上它已经是正确的类了,你可以不强制转换v.yourStuffInB = 11

qf9go6mv

qf9go6mv3#

你不能这么做。而不是子类创建'交互管理器'类,或状态管理器类。然后,基本视图控制器将被提供一个管理器示例作为分段的一部分,并且它将所有UI交互转发给管理器以进行处理。然后,根据需要,在故事板中有一个VC,并且可以提供一个新的或编辑管理器。管理器也可以有视图控制器不关心的特定示例变量。

相关问题