Подтвердить что ты не робот

Мгновенный просмотр контроллера просмотра из раскадровки против создания нового экземпляра

Какова функциональная разница между созданием экземпляра View Controller из раскадровки и созданием нового экземпляра? Например:

#import "SomeViewController.h"

...

SomeViewController *someViewController = [SomeViewController new];

против

#import "SomeViewController.h"

...

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

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

В любом случае, someViewController эффективно то же самое?

4b9b3361

Ответ 1

Основное отличие заключается в том, как создаются экземпляры вашего UIViewController.

Во втором случае все представления, созданные вами в раскадровке, будут автоматически создаваться для вас, и все выходы и действия будут настроены так, как вы указали в раскадровке.

В первом случае это не происходит; вы просто получаете необработанный объект. Вам нужно будет выделить и создать экземпляр всех ваших подзонов, выложить их с помощью ограничений или иным образом и самостоятельно подключить все выходы и действия. Apple рекомендует сделать это, переопределив метод loadView UIViewController.

Ответ 2

Во втором случае контроллер просмотра загрузит свой вид из раскадровки, и вы будете счастливы.

В первом случае это не будет. Если вы не сделали другие шаги (например, переопределить loadView или viewDidLoad или создать xib с именем SomeViewController.xib), вы просто получите пустой белый вид и будете грустны.

Ответ 3

Это не одно и то же. В раскадровке у вас, вероятно, есть элементы интерфейса. У них могут быть ограничения и свойства, установленные через раскадровку. Когда вы создаете экземпляр viewcontroller через раскадровку, вы получаете все инструкции о том, где находятся эти подпункты и каковы их свойства. Если вы просто скажете [SomeViewController new], вы не получите все инструкции, которые имеет раскадровка для контроллера вида.

Хорошим тестом будет добавить UIViewController в раскадровку и перетащить на него красный вид. Создайте его с помощью обоих методов и посмотрите, какие различия существуют.

Ответ 4

В Swift вы можете сделать то же самое с

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

Вам нужно будет указать Идентификатор в раскадровке в SomeViewController и отметьте галочкой значение Использовать идентификатор раскадровки

Ответ 5

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

Ответ 6

Если вы не хотите создавать экземпляр нового VC с помощью instantiateViewControllerWithIdentifier, но обращаетесь к экземпляру, созданному раскадровкой из AppDelegate:

  • создать свойство в AppDelegate.h, поэтому он будет доступен из классов, используя его @property (nonatomic, strong) myViewControllerClass*vC;
  • in viewDidLoad внутри myViewControllerClass.m Я обращаюсь к общему экземпляру AppDelegate и передаю свойство self: [AppDelegate sharedInstance].vC = self;

Мне пришлось использовать это решение в сложной раскадровке и до сих пор не может понять, что я не могу найти простой способ получить доступ ко всем (или, по крайней мере, тем, которые мне нужны) объектам в раскадровке, просто обратившись к их идентификаторам.

Ответ 7

Еще одна вещь, которую нужно проверить, - это если диспетчер представлений, который бросает ошибку, имеет идентификатор storyboardIdentifier, вы можете проверить xib файл раскадровки.

идентификатор отсутствовал в моем случае, ошибка прекратилась, когда я добавил его