【问题标题】:Subclass ViewController from Storyboard来自 Storyboard 的子类 ViewController
【发布时间】:2015-12-09 22:32:55
【问题描述】:

我在 Storyboard 中创建了 ViewController,我正在使用

instantiateViewControllerWithIdentifier:

加载它。但我需要将这个 VC 作为基类并使用 3-4 个子类来更改其属性。

如何使用instantiateViewControllerWithIdentifier 获取我的子类的实例?

【问题讨论】:

标签: ios objective-c uiview uiviewcontroller storyboard


【解决方案1】:

Swift 3 中的@Bhagyesh 版本:

class func instantiateFromSuperclassStoryboard() -> SubclassViewController {
    let stroryboard = UIStoryboard(name: "Main", bundle: nil)
    let controller = stroryboard.instantiateViewController(withIdentifier: "BaseViewController")
    object_setClass(controller, SubclassViewController.self)

    return controller as! SubclassViewController
}

【讨论】:

    【解决方案2】:

    您将不得不使用对象 c 运行时。覆盖子类的 init 方法。使用“instantiateViewControllerWithIdentifier”创建一个 BaseViewController 对象。然后使用 objc_setClass 方法为创建的对象设置类。 以下代码将进入 SubclassViewController.m。

        - (instancetype)init {
          UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"main" bundle:[NSBundle mainBundle]];
          UIViewController *baseClassViewController = [storyboard instantiateViewControllerWithIdentifier:@"baseClassIdentifier"];
    
          object_setClass(baseClassViewController, [SubclassViewController class]);
          return (SubclassViewController *)baseClassViewController;
        }
    

    在此之后,您可以使用简单的 [[SubclassViewController alloc] init] 创建 SubclassViewController 对象。

    【讨论】:

    • 遗憾的是,如果子类包含任何额外的实例变量,则会崩溃。那是因为object_setClass 只是更改了isa 指针。它不分配任何额外的空间。一旦你尝试访问一个额外的变量,boom。
    【解决方案3】:

    只需投射即可。

    MyController *controller = (MyController *)[self.storyboard instantiateViewControllerWithIdentifier:@"myController"];
    

    或斯威夫特:

    let controller = storyboard?.instantiateViewControllerWithIdentifier("myController") as! MyController
    

    【讨论】:

    • 但是如果我需要创建 MyControllerSubclass1 从情节提要中创建 MyController 的子类,ID 为“myController”?
    • 无论您在情节提要中为视图控制器提供什么 ID。
    • 不,在这种情况下不起作用,您将收到运行时错误:Could not cast value of type 'YourApp.BaseViewController' (0x10e435d48) to 'YourApp.SubclassViewController' (0x10e435a68).
    猜你喜欢
    • 2019-03-28
    • 2015-10-05
    • 2012-04-13
    • 1970-01-01
    • 2016-01-19
    • 2023-03-24
    • 2015-05-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多