ios 从故事板实例化视图控制器与创建新实例

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/26131693/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 02:56:16  来源:igfitidea点击:

Instantiate View Controller from Storyboard vs. Creating New Instance

iosobjective-cuiviewcontrolleruistoryboard

提问by Benjamin Martin

What is the functional difference between instantiating a View Controller from the storyboard and creating a new instance of it? For example:

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

#import "SomeViewController.h"

...

SomeViewController *someViewController = [SomeViewController new];

versus

相对

#import "SomeViewController.h"

...

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];

SomeViewController *someViewController = [storyboard instantiateViewControllerWithIdentifier:@"SomeViewController"];

In either case, is someViewControllereffectively the same thing?

在这两种情况下,someViewController实际上是同一件事吗?

采纳答案by dpassage

The main difference is in how the subviews of your UIViewControllerget instantiated.

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

In the second case, all the views you create in your storyboard will be automatically instantiated for you, and all the outlets and actions will be set up as you specified in the storyboard.

在第二种情况下,您在故事板中创建的所有视图都将自动为您实例化,并且所有出口和操作都将按照您在故事板中的指定进行设置。

In the first, case, none of that happens; you just get the raw object. You'll need to allocate and instantiate all your subviews, lay them out using constraints or otherwise, and hook up all the outlets and actions yourself. Apple recommendsdoing this by overriding the loadViewmethod of UIViewController.

在第一种情况下,这些都不会发生;你只是得到原始对象。您需要分配和实例化所有子视图,使用约束或其他方式布置它们,并自己连接所有出口和动作。苹果公司建议通过重写这样loadView的方法UIViewController

回答by rob mayoff

In the second case, the view controller will load its view from the storyboard and you will be happy.

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

In the first case, it won't. Unless you've taken other steps (like overriding loadViewor viewDidLoador creating a xib named SomeViewController.xib), you'll just get an empty white view and be sad.

在第一种情况下,它不会。除非您采取了其他步骤(例如覆盖loadViewviewDidLoad创建名为 的 xib SomeViewController.xib),否则您只会得到一个空白的白色视图并感到悲伤。

回答by Joseph

In Swift you can do the same with,

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

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

You will need to give the Identifierin the Storyboard to the SomeViewController and tick the checkmark to Use Storyboard ID

您需要将 Storyboard 中的标识符提供给SomeViewController 并勾选使用 Storyboard ID的复选标记

回答by Kris Gellci

It is not the same thing. In the storyboard you probably have some UI elements laid out. They might have constraints and properties setup through the storyboard. When you instantiate the viewcontroller via the storyboard, you are getting all the instructions for where those subviews are and what their properties are. If you just say [SomeViewController new]you are not getting all the instructions that the storyboard has for the view controller.

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

A nice test will be to add a UIViewController to a storyboard and drag a red view onto it. Instantiate it using both methods and see what the differences are.

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

回答by Shan Shafiq

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
        }
    }

回答by Lookaji

In case you don't want to instantiate a new VC using instantiateViewControllerWithIdentifierbut accessing the instance created by the storyboard from the AppDelegate:

如果您不想使用instantiateViewControllerWithIdentifier但从 AppDelegate 访问故事板创建的实例来实例化新的 VC :

  1. create a property in AppDelegate.h so it will be accessible from classes using it @property (nonatomic, strong) myViewControllerClass*vC;
  2. in viewDidLoadinside myViewControllerClass.m I access the shared instance of AppDelegate and feed the property with self: [AppDelegate sharedInstance].vC = self;
  1. 在 AppDelegate.h 中创建一个属性,以便可以从使用它的类访问它 @property (nonatomic, strong) myViewControllerClass*vC;
  2. viewDidLoadmyViewControllerClass.m 中,我访问 AppDelegate 的共享实例并使用 self 提供属性:[AppDelegate sharedInstance].vC = self;

I had to use this solution in a complex storyboard and still can't get over the fact that I cannot find an easy way to access all (or at least the ones I need)objects in storyboard simply by addressing their identifiers.

我不得不在一个复杂的故事板中使用这个解决方案,但仍然无法克服这样一个事实,即我无法找到一种简单的方法来访问故事板中的所有(或至少是我需要的)对象,只需解决它们的标识符。

回答by megaKertz

another thing to check for is if the viewcontroller that's throwing the error has a storyboardIdentifier, you can check the storyboard xib file.

要检查的另一件事是,如果抛出错误的视图控制器有一个 storyboardIdentifier,你可以检查 storyboard xib 文件。

the identifier was missing in my case, the error stopped when i added it

在我的情况下缺少标识符,当我添加它时错误停止了