【问题标题】:How can I load storyboard programmatically from class?如何以编程方式从课堂上加载故事板?
【发布时间】:2012-04-11 09:21:18
【问题描述】:

我的问题是我正在寻找同时使用 storyboardxib 的方法。但是我找不到以编程方式加载和显示故事板的正确方法。项目开始使用 xib 开发,现在很难将所有 xib 文件嵌套在情节提要中。所以我一直在寻找一种在代码中实现它的方法,比如使用 alloc, init, push 用于 viewControllers。在我的例子中,我在情节提要中只有一个控制器:UITableViewController,它有一些我想要显示的内容的静态单元格。如果有人知道在不进行大量重构的情况下使用 xib 和故事板的正确方法,我将不胜感激。

【问题讨论】:

    标签: ios objective-c xcode storyboard xib


    【解决方案1】:

    在您的故事板中,转到属性检查器并设置视图控制器的标识符。然后,您可以使用以下代码呈现该视图控制器。

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

    【讨论】:

    • [sb instantiateInitialViewController] 如果你想从场景的默认视图控制器开始,很方便。
    • 詹姆斯,谢谢!我一直在寻找相当长的时间来试图弄清楚如何实例化 Storyboard 的视图。你的答案(和 kokoko 的问题)令人耳目一新。
    • 在 James Beith 的代码中,如果 UIViewControler *vc 与当前视图控制器来回切换,则必须重用它。我发现 vc 一直存在并连接到情节提要笔尖的困难方式,直到用户按下新视图上的按钮,现在该代码的先前咒语中丢弃的 vc 存在内存泄漏。跨度>
    • 如果有人想知道如何在应用程序委托中执行此操作,请按以下顺序将 [self presentViewcontroller] 逻辑替换为这些行:1) self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 2) self.window.rootViewController = vc; 和 3 )[self.window makeKeyAndVisible];。您也可以去掉 modalTransitionStyle 行,因为这不是来自应用委托的模态转换。
    • 仅供参考,如果您想“推动”新故事板而不是模态弹出,请查看 chaithraVeeresh 的答案。
    【解决方案2】:

    斯威夫特 3

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

    斯威夫特 2

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

    先决条件

    为您的视图控制器分配一个 Storyboard ID

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

    Swift(旧版)

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

    编辑:Fred A. 的评论中建议使用 Swift 2

    如果你想在没有任何 navigationController 的情况下使用,你必须使用如下:

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

    【讨论】:

    • 在 Swift 2 中,不需要添加“as?UIViewController”,编译器会自动判断
    • 或者你可以做self.storyboard并合并line1&2
    【解决方案3】:

    在属性检查器中给出该视图控制器的标识符,下面的代码适用于我

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

    【讨论】:

      【解决方案4】:

      试试这个

      UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
      UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier:@"Login"];
      
      [[UIApplication sharedApplication].keyWindow setRootViewController:vc];
      

      【讨论】:

      • 如果您不使用 UINavigationController,请使用此选项,如其他答案所示
      【解决方案5】:

      在 swift
      NavigationControllerpushController 中您可以替换为

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

      【讨论】:

        【解决方案6】:

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

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

        【讨论】:

          【解决方案7】:

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

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

          将同时加载StoryboardUIViewControllervc 的类型为ModalAlertViewController注意假设storyboard的Storyboard ID与storyboard同名,并且storyboard已经被标记为Is Initial View Controller

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

          【讨论】:

            【解决方案8】:

            对于 swift 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 中加载 Storyboard:

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

            }

            当您创建新的 Storyboard 时,只需在 StoryboardID 上设置相同的名称并在您的枚举“StoryBoardName”中添加 Storyboard 名称

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-08-29
              • 1970-01-01
              • 2012-02-04
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多