Como posso carregar o storyboard programaticamente da aula?


183

Meu problema é que eu estava procurando uma maneira de usar o storyboard e o xib . Mas não consigo encontrar uma maneira adequada de carregar e mostrar o storyboard programaticamente. O projeto foi iniciado com o xib e agora é muito difícil aninhar todos os arquivos xib no storyboard. Então, eu estava procurando uma maneira de fazer isso em código, como no alloc, init, pushviewControllers. No meu caso, tenho apenas um controlador no storyboard:, UITableViewControllerque possui células estáticas com algum conteúdo que quero mostrar. Se alguém souber a maneira correta de trabalhar tanto com o xib quanto com o storyboard sem grandes refatorações, agradecerei por qualquer ajuda.

Respostas:


370

No seu storyboard, vá ao inspetor Attributes e defina o Identifier do controlador de exibição. Você pode apresentar esse controlador de exibição usando o código a seguir.

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

65
[sb instantiateInitialViewController]é útil se você deseja iniciar no controlador de exibição padrão da cena.
drewish

James, obrigado! Estou procurando há algum tempo tentando descobrir como instanciar a exibição de um Storyboard. Sua resposta (e a pergunta de kokoko) é mais refrescante de encontrar.
bejonbee

No código de James Beith, é preciso reutilizar esse UIViewControler * vc se ele for alternado com o atual controlador de exibição. Eu descobri da maneira mais difícil que o vc fica por perto e é conectado à ponta do storyboard até o usuário pressionar um botão na nova visualização, e agora há um vazamento de memória com o vc descartado dos encantamentos anteriores deste código.
SWoo

11
Caso alguém queira saber como fazer isso no delegado do aplicativo, substitua a [self presentViewcontroller]lógica por estas linhas na seguinte ordem: 1) self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];2) self.window.rootViewController = vc;e 3) [self.window makeKeyAndVisible];. Você também pode provavelmente se livrar da modalTransitionStylelinha, porque essa não é uma transição modal do delegado do aplicativo.
precisa saber é o seguinte

Para sua informação, se você quiser "empurrar" o novo storyboard em vez de aparecer modalmente, veja a resposta de chaithraVeeresh.
Adam Johns

76

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)

Pré-requisito

Atribua um ID do Storyboard ao seu controlador de exibição.

ID do storyboard

IB> Mostrar o inspetor de identidade> Identidade> ID do storyboard

Swift (legado)

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

Edit: Swift 2 sugerido em um comentário por Fred A.

se você deseja usar sem nenhum controlador de navegação, use o seguinte:

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

1
No Swift 2, você não precisa adicionar "as? UIViewController", o compilador determina automaticamente
Frédéric Adda

2
ou você pode simplesmente fazer self.storyboarde mesclar as linhas 1 e 2
Honey

17

No inspetor de atributos, forneça o identificador para esse controlador de exibição e o código abaixo funciona para mim

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

5

Tente isto

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

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

Use isto se você não estiver usando um UINavigationController como mostrado em outras respostas
latenitecoder

2

no rápido
NavigationController e pushController, você pode substituir por

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

1

Nos swift 3 e 4 , você pode fazer isso. A boa prática é definir o nome do Storyboard igual ao 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)
   }
}

e então você pode carregar seu Storyboard no seu ViewController da seguinte maneira:

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

}

Ao criar um novo Storyboard, defina o mesmo nome no StoryboardID e adicione o nome do Storyboard na sua enumeração " StoryBoardName "


0

Você sempre pode pular direto para o controlador raiz:

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

0

A extensão abaixo permitirá que você carregue um Storyboarde está associado UIViewController. Exemplo: Se você tem um UIViewControllerchamado ModalAlertViewControllere um storyboard com o nome "ModalAlert" eg

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

Irá carregar tanto o Storyboarde UIViewControllere vcserá do tipo ModalAlertViewController. Nota Supõe que o ID do storyboard do storyboard tenha o mesmo nome que o storyboard e que o storyboard tenha sido marcado como É o controlador de exibição inicial .

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
    }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.