Создание и представление viewController в Swift

Проблема

Я начал смотреть новый Swift на Xcode 6, и я попробовал некоторые демонстрационные проекты и учебные пособия. Теперь я застрял в:

Создание и представление viewController из определенной раскадровки

Objective-C Решение

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"myStoryboardName" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"myVCID"];
[self presentViewController:vc animated:YES completion:nil];

Как это сделать на Swift?

Ответ 1

Все дело в новом синтаксисе, функциональность не изменилась:

// Swift 3.0

let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "someViewController")
self.present(controller, animated: true, completion: nil)

Если у вас возникли проблемы с init(coder:), обратитесь к Ответу EridB.

Ответ 2

Для пользователей, использующих @akashivskyy answer для создания экземпляра UIViewController и имеющих исключение:

фатальная ошибка: использование нереализованного инициализатора 'init (coder:)' для класса

Быстрый совет:

Вручную внедрить required init?(coder aDecoder: NSCoder) в пункт назначения UIViewController, который вы пытаетесь создать

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}

Если вам нужно больше описания, пожалуйста, обратитесь к моему ответу здесь

Ответ 3

Эта ссылка имеет обе версии:

Swift:

let viewController:UIViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("ViewController") as UIViewController
self.presentViewController(viewController, animated: false, completion: nil)

Цель C

UIViewController *viewController = [[UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:@"ViewController"];

У этой ссылки есть код для запуска viewcontroller в том же раскадровке

/*
 Helper to Switch the View based on StoryBoard
 @param StoryBoard ID  as String
*/
func switchToViewController(identifier: String) {
    let viewController = self.storyboard?.instantiateViewControllerWithIdentifier(identifier) as! UIViewController
    self.navigationController?.setViewControllers([viewController], animated: false)

}

Ответ 4

акашивский ответ работает просто отлично! Но, если у вас есть проблемы с возвратом из представленного контроллера представления, эта альтернатива может быть полезна. Это сработало для меня!

Swift:

let storyboard = UIStoryboard(name: "MyStoryboardName", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("someViewController") as! UIViewController
// Alternative way to present the new view controller
self.navigationController?.showViewController(vc, sender: nil)

Obj-C:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MyStoryboardName" bundle:nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"someViewController"];
[self.navigationController showViewController:vc sender:nil];

Ответ 5

// "Main" is name of .storybord file "
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
// "MiniGameView" is the ID given to the ViewController in the interfacebuilder
// MiniGameViewController is the CLASS name of the ViewController.swift file acosiated to the ViewController
var setViewController = mainStoryboard.instantiateViewControllerWithIdentifier("MiniGameView") as MiniGameViewController
var rootViewController = self.window!.rootViewController
rootViewController?.presentViewController(setViewController, animated: false, completion: nil)

Это сработало для меня, когда я положил его в AppDelegate

Ответ 6

Если вы хотите представить его модально, вы должны иметь что-то вроде ниже:

let vc = self.storyboard!.instantiateViewControllerWithIdentifier("YourViewControllerID")
self.showDetailViewController(vc as! YourViewControllerClassName, sender: self)

Ответ 7

Если у вас есть Viewcontroller, не использующий раскадровку /Xib, вы можете нажать на этот конкретный VC, как показано ниже:

 let vcInstance : UIViewController   = yourViewController()
 self.present(vcInstance, animated: true, completion: nil)

Ответ 8

Swift 4:

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let yourVC: YourVC = storyboard.instantiateViewController(withIdentifier: "YourVC") as! YourVC

Ответ 9

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

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

Например, контроллер представления с именем vc1 в Main.storyboard будет создан таким образом:

let vc: UIViewController = R.storyboard.Main.vc1^  // where the '^' character initialize the controller

Ответ 10

Свифт 3 Storyboard

let settingStoryboard : UIStoryboard = UIStoryboard(name: "SettingViewController", bundle: nil)
let settingVC = settingStoryboard.instantiateViewController(withIdentifier: "SettingViewController") as! SettingViewController
self.present(settingVC, animated: true, completion: {

})

Ответ 11

Независимо от того, что я пробовал, это просто не сработало для меня - никаких ошибок, но на моем экране не было нового контроллера представления. Не знаю, почему, но, завернув его в тайм-аут, наконец-то это заработало:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.0) {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let controller = storyboard.instantiateViewController(withIdentifier: "TabletViewController")
    self.present(controller, animated: true, completion: nil)
}

Ответ 12

Я хотел бы предложить гораздо более чистый способ. Это будет полезно, если у нас будет несколько раскадровки

1. Создайте структуру со всеми вашими раскадными досками

struct Storyboard {
      static let main = "Main"
      static let login = "login"
      static let profile = "profile" 
      static let home = "home"
    }

2. Создайте расширение UIStoryboard, подобное этому

extension UIStoryboard {
  @nonobjc class var main: UIStoryboard {
    return UIStoryboard(name: Storyboard.main, bundle: nil)
  }
  @nonobjc class var journey: UIStoryboard {
    return UIStoryboard(name: Storyboard.login, bundle: nil)
  }
  @nonobjc class var quiz: UIStoryboard {
    return UIStoryboard(name: Storyboard.profile, bundle: nil)
  }
  @nonobjc class var home: UIStoryboard {
    return UIStoryboard(name: Storyboard.home, bundle: nil)
  }
}

Дайте идентификатор раскадровки в качестве имени класса и используйте приведенный ниже код для создания экземпляра

let loginVc = UIStoryboard.login.instantiateViewController(withIdentifier: "\(LoginViewController.self)") as! LoginViewController

Ответ 13

Я создал библиотеку, которая будет обрабатывать это намного проще с лучшим синтаксисом:

https://github.com/Jasperav/Storyboardable

Просто измените Storyboard.swift и пусть ViewControllers соответствуют Storyboardable.

Ответ 14

Обновленный код Swift 4.2

let storyboard = UIStoryboard(name: "StoryboardNameHere", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "ViewControllerNameHere")
self.present(controller, animated: true, completion: nil)