从Storyboard实例化View Controller与创build新实例

从故事板实例化视图控制器和创build它的新实例之间的function区别是什么? 例如:

#import "SomeViewController.h" ... SomeViewController *someViewController = [SomeViewController new]; 

 #import "SomeViewController.h" ... UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil]; SomeViewController *someViewController = [storyboard instantiateViewControllerWithIdentifier:@"SomeViewController"]; 

在任何情况下, someViewController有效地是相同的东西?

主要区别在于你的UIViewController的子视图是如何实例化的。

在第二种情况下,您在故事板中创build的所有视图都将自动为您实例化,所有sockets和动作将按照您在故事板中指定的方式进行设置。

在第一种情况下,没有一件事情发生。 你只是得到原始对象。 您需要分配和实例化所有子视图,使用约束或其他方式将其展开,并自行连接所有的sockets和操作。 苹果build议通过覆盖UIViewControllerloadView方法来做到这一点。

在第二种情况下,视图控制器将从故事板加载它的视图,并且您会很高兴。

在第一种情况下,它不会。 除非你已经采取了其他的步骤(比如重写loadView或者viewDidLoad或者创build一个名为SomeViewController.xib ), SomeViewController.xib你只会得到一个空的白色视图而且很伤心。

这不是一回事。 在故事板中,您可能已经布置了一些UI元素。 他们可能会通过故事板设置约束和属性。 当您通过故事板实例化视图控制器时,您将获得有关这些子视图的位置以及它们的属性的所有说明。 如果你只是说[SomeViewController new]你没有得到故事板对视图控制器的所有说明。

一个不错的testing是将UIViewController添加到故事板,并将红色的视图拖到它上面。 使用两种方法实例化它,看看有什么不同。

在Swift中你可以做同样的事情,

 var someVC = self.storyboard?.instantiateViewControllerWithIdentifier("SomeViewController") as! SomeViewController 

您需要将Storyboard中的Identifier赋予SomeViewController,并勾选勾选Use Storyboard ID

 simple swift 3 extension fileprivate enum Storyboard : String { case main = "Main" } fileprivate extension UIStoryboard { static func loadFromMain(_ identifier: String) -> UIViewController { return load(from: .main, identifier: identifier) } static func load(from storyboard: Storyboard, identifier: String) -> UIViewController { let uiStoryboard = UIStoryboard(name: storyboard.rawValue, bundle: nil) return uiStoryboard.instantiateViewController(withIdentifier: identifier) } } // MARK: App View Controllers extension UIStoryboard { class func loadHomeViewController() -> HomeViewController { return loadFromMain("HomeViewController") as! HomeViewController } } 

如果你不想使用instantiateViewControllerWithIdentifier实例化一个新的VC,但是访问由AppDelegate中的故事板创build的实例:

  1. 在AppDelegate.h中创build一个属性,这样它就可以通过使用它的类来访问@property (nonatomic, strong) myViewControllerClass*vC;
  2. 在myViewControllerClass.m中的viewDidLoad ,我访问AppDelegate的共享实例,并用self提供属性: [AppDelegate sharedInstance].vC = self;

我不得不在一个复杂的故事板中使用这个解决scheme,但仍然无法克服这个事实,即我无法简单地通过解决它们的标识符来find在故事板中访问所有(或者至less我需要的)对象的简单方法。

另一件要检查的是,如果抛出错误的viewcontroller有一个storyboardIdentifier,你可以检查故事板xib文件。

在我的情况下,标识符丢失,当我添加它时,错误停止