我如何从类编程加载故事板?

我的问题是,我正在寻找使用 故事板西布的方法。但是我不能找到适当的方法来加载和程序化地显示故事板。项目是从 xib 开始开发的,现在很难在情节串连板中嵌套所有 xib 文件。所以我在寻找一种用代码实现的方法,比如用 alloc, init, push实现 viewController。在我的示例中,情节串连图板中只有一个控制器: UITableViewController,它有一些带有我想要显示的内容的静态单元格。如果有人知道如何在不进行大规模重构的情况下使用 xib 和情节串连图板,我将非常感谢您的帮助。

151557 次浏览

在你的故事板中,去属性检查器并设置视图控制器的标识符。然后可以使用以下代码显示该视图控制器。

UIStoryboard *sb = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:@"myViewController"];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:vc animated:YES completion:NULL];

在属性检查器中给出视图控制器的标识符,下面的代码对我有效

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
DetailViewController *detailViewController = [storyboard instantiateViewControllerWithIdentifier:@"DetailViewController"];
[self.navigationController pushViewController:detailViewController animated:YES];

试试这个

UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier:@"Login"];


[[UIApplication sharedApplication].keyWindow setRootViewController:vc];

Swift 3

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "viewController")
self.navigationController!.pushViewController(vc, animated: true)

Swift 2

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("viewController")
self.navigationController!.pushViewController(vc, animated: true)

先决条件

为视图控制器分配一个 故事板 ID

Storyboard ID

IB > 显示身份检查员 > 身份 > 故事板 ID

迅捷(遗产)

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewControllerWithIdentifier("viewController") as? UIViewController
self.navigationController!.pushViewController(vc!, animated: true)

编辑: 在 弗雷德 · A。的评论中建议的 Swift 2

如果你不想使用任何导航控制器,你必须像下面这样使用:

    let Storyboard  = UIStoryboard(name: "Main", bundle: nil)
let vc = Storyboard.instantiateViewController(withIdentifier: "viewController")
present(vc , animated: true , completion: nil)

以迅雷不及掩耳之势
可以替换的 NavigationController 推动控制器

present(vc, animated:true , completion: nil)

对于 雨燕4号和5号,您可以这样做。好的实践是将 Storyboard 的名称设置为等于 StoryboardID。

enum StoryBoardName{
case second = "SecondViewController"
}
extension UIStoryboard{
class func load(_ storyboard: StoryBoardName) -> UIViewController{
return UIStoryboard(name: storyboard.rawValue, bundle: nil).instantiateViewController(withIdentifier: storyboard.rawValue)
}
}

然后你可以像这样在 ViewController 中加载你的故事板:

class MyViewController: UIViewController{
override func viewDidLoad() {
super.viewDidLoad()
guard let vc = UIStoryboard.load(.second) as? SecondViewController else {return}
self.present(vc, animated: true, completion: nil)
}

}

当您创建一个新的故事板只是设置相同的名称在 StoryboardID 和添加故事板名称在您的枚举“ StoryBoardName

您总是可以直接跳转到根控制器:

UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
UIViewController *vc = [storyboard instantiateInitialViewController];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:vc animated:YES completion:NULL];

下面的扩展将允许您加载 Storyboard及其相关的 UIViewController。例如: 如果你有一个名为 ModalAlertViewControllerUIViewController和一个名为“ ModalAlert”的故事板。

let vc: ModalAlertViewController = UIViewController.loadStoryboard("ModalAlert")

将负载 StoryboardUIViewControllervc都将是类型 ModalAlertViewController。假设故事板的故事板 ID 与故事板具有相同的名称,并且故事板已经被标记为 初始视图控制器

extension UIViewController {
/// Loads a `UIViewController` of type `T` with storyboard. Assumes that the storyboards Storyboard ID has the same name as the storyboard and that the storyboard has been marked as Is Initial View Controller.
/// - Parameter storyboardName: Name of the storyboard without .xib/nib suffix.
static func loadStoryboard<T: UIViewController>(_ storyboardName: String) -> T? {
let storyboard = UIStoryboard(name: storyboardName, bundle: nil)
if let vc = storyboard.instantiateViewController(withIdentifier: storyboardName) as? T {
vc.loadViewIfNeeded() // ensures vc.view is loaded before returning
return vc
}
return nil
}
}