【问题标题】:Storyboard and custom init故事板和自定义初始化
【发布时间】:2013-08-22 07:25:38
【问题描述】:

我最近尝试在 Xcode 中使用 MainStoryboard.storyboard,到目前为止一切顺利,我想知道为什么我以前从未使用过它。在玩一些代码时,我遇到了一个障碍,我不知道如何解决这个问题。

当我分配并初始化一个新的 ViewController(使用我在 ViewControllers 类中声明的自定义初始化)时,我会做这样的事情:

ViewController *myViewController = [[ViewController alloc] initWithMyCustomData:myCustomData];

然后我可以做类似的事情:

[self presentViewController:myViewController animated:YES completion:nil];

当我使用故事板时,我了解到切换到独立的 ViewController 需要一个标识符。

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
ViewController *myViewController = [storyboard instantiateViewControllerWithIdentifier:@"MyViewControllerIdentifier"];
[self presentViewController:myViewController animated:YES completion:nil];

在使用情节提要的同时,我怎样才能仍然为 myViewController 使用我的自定义初始化?

这样做可以吗:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
ViewController *myViewController = [storyboard instantiateViewControllerWithIdentifier:@"MyViewControllerIdentifier"];
myViewController.customData = myCustomData;
[self presentViewController:myViewController animated:YES completion:nil];




//MyViewController.m
- (id) initWithMyCustomData:(NSString *) data {
if (self = [super init]) {
    iVarData = data;
}
return self;
}

【问题讨论】:

    标签: objective-c uiviewcontroller storyboard


    【解决方案1】:

    我只想创建一个方法来加载自定义数据。

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    MyViewController *myViewController = [storyboard instantiateViewControllerWithIdentifier:@"MyViewControllerIdentifier"];
    [myViewController loadCustomData:myCustomData];
    [self presentViewController:myViewController animated:YES completion:nil];
    

    如果您的所有initWithCustomData 方法只设置一个实例变量,您应该手动设置它(不需要自定义初始化或额外方法):

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    MyViewController *myViewController = [storyboard instantiateViewControllerWithIdentifier:@"MyViewControllerIdentifier"];
    myViewController.iVarData = myCustomData;
    [self presentViewController:myViewController animated:YES completion:nil];
    

    【讨论】:

    • 谢谢。 Apple 没有提供一种使用 Storyboards 创建适当的自定义 init 方法的方法,这似乎很疯狂。
    • 我不知道为什么有人会说:“如果您的 initWithCustomData 方法所做的只是设置一个实例变量,您应该手动设置它(不需要自定义初始化或额外的方法)”。没有来自 Apple 的文档说明这一点,因此我建议任何读者将此声明视为仅是意见,而不是要遵循的规则。 iOS 中的许多初始化程序甚至只接受一个参数。
    • @zumzum Apple 在他们的示例代码中确实使用了在 'prepareForSegue: sender:' 方法中设置变量的做法。有关示例,请参见 EKReminderSuite 示例项目中的“AddTimedReminder.m”文件。
    • @zumzum 是的,这是我的意见。当它可以直接设置时,创建一个方法来设置一个实例变量似乎毫无意义。显然有些初始化器只接受一个参数;但是,在这种情况下,创建自定义初始化是一个挑战,我相信这是一个更简单的攻击角度。
    【解决方案2】:

    您可以在 -init 方法中实例化视图控制器。

     - (instancetype)init
     {
        UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
    
       self = [storyboard instantiateViewControllerWithIdentifier:@"MyViewController"];
    
       if(self)
       {
        //default initialization
    
       }
       return  self;
     }
    

    在你的自定义初始化方法中

     - (instancetype)initWithImages:(NSArray *)images
     {
       self = [self init];
    
       if(self)
       {
         self.images = images;
       }
    
       return  self;
     }
    

    【讨论】:

    • 不幸的是,这个解决方案不再是“风水”了,因为你的 - (instancetype)init 没有调用超类指定的初始化器。
    【解决方案3】:

    我的版本:

    - (instancetype)initWithData (NSArray *)someData
     {
        UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
    
       self = [storyboard instantiateViewControllerWithIdentifier:@"MyViewController"];
    
       if(self)
       {
        //default initialization
    
       }
       return  self;
     }
    

    ...一个初始化器 ;)

    【讨论】:

      猜你喜欢
      • 2015-08-07
      • 2018-11-16
      • 1970-01-01
      • 1970-01-01
      • 2017-06-10
      • 1970-01-01
      • 1970-01-01
      • 2016-03-30
      相关资源
      最近更新 更多