Jak mogę załadować planszę programowo z klasy?


183

Mój problem polega na tym, że szukałem sposobu na użycie zarówno scenorysów, jak i Xib . Ale nie mogę znaleźć odpowiedniego sposobu na programowe ładowanie i wyświetlanie scenorysu. Projekt zaczął się rozwijać w Xib, a teraz bardzo trudno jest zagnieździć wszystkie pliki Xib w scenorysie. Szukałem więc sposobu na zrobienie tego w kodzie, tak jak w alloc, init, pushprzypadku viewControllers. W moim przypadku mam tylko jeden kontroler w serii ujęć: UITableViewControllerktóry ma statyczne komórki z pewną zawartością, którą chcę pokazać. Jeśli ktoś zna właściwy sposób pracy zarówno z Xibem, jak i Storyboard bez wielkiego refaktoryzacji, będę wdzięczny za wszelką pomoc.

Odpowiedzi:


370

W swoim scenorysie przejdź do Inspektora atrybutów i ustaw identyfikator kontrolera widoku. Następnie możesz przedstawić ten kontroler widoku za pomocą następującego kodu.

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]jest przydatny, jeśli chcesz uruchomić na domyślnym kontrolerze sceny.
— zwrócił uwagę

James, dziękuję! Od dłuższego czasu próbuję wymyślić, jak utworzyć instancję widoku Storyboard. Twoja odpowiedź (i pytanie kokoko) jest najbardziej odświeżająca.
— bejonbee

W kodzie Jamesa Beitha należy ponownie użyć tego UIViewControler * vc, jeśli jest on przełączany w tę iz powrotem z bieżącym kontrolerem widoku. Dowiedziałem się, w jaki sposób vc trzyma się i jest podłączony do końcówki scenorysu, dopóki użytkownik nie naciśnie przycisku w nowym widoku, a teraz jest wyciek pamięci z tym odrzuconym vc z poprzednich inkantacji tego kodu.
— SWoo

11
Jeśli ktoś chce wiedzieć, jak to zrobić w delegacie aplikacji, zamień [self presentViewcontroller]logikę na te wiersze w następującej kolejności: 1) self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];2) self.window.rootViewController = vc;i 3) [self.window makeKeyAndVisible];. Prawdopodobnie możesz również pozbyć się modalTransitionStylelinii, ponieważ nie jest to modalne przejście z delegata aplikacji.
— lewiguez

Do Twojej wiadomości, jeśli chcesz „wypchnąć” nową scenoryskę zamiast wyskakiwać modalnie, spójrz na odpowiedź chaithraVeeresh.
— Adam Johns

76

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

Warunek wstępny

Przypisz identyfikator scenorysu do kontrolera widoku.

Identyfikator serii ujęć

IB> Pokaż inspektora tożsamości> Tożsamość> Identyfikator scenorysu

Swift (starsza wersja)

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

Edycja: Swift 2 zasugerowany w komentarzu Freda A.

jeśli chcesz korzystać bez nawigacji Sterownik musisz użyć w następujący sposób:

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

1
W Swift 2 nie trzeba dodawać „as? UIViewController”, kompilator określa to automatycznie
— Frédéric Adda,

2
lub możesz po prostu zrobić self.storyboardi połączyć linię 1 i 2
— Honey

17

W inspektorze atrybutów podaj identyfikator tego kontrolera widoku, a poniższy kod działa dla mnie

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

5

Spróbuj tego

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

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

Użyj tego, jeśli nie używasz UINavigationController, jak pokazano w innych odpowiedziach
— latenitecoder 10.09.17

2

w szybkim nawigatorze
NavigationController i pushController, który możesz zastąpić

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

1

W przypadku szybkich 3 i 4 możesz to zrobić. Dobrą praktyką jest ustawienie nazwy StoryboardID równej 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)
   }
}

a następnie możesz załadować Storyboard do ViewController w następujący sposób:

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

}

Podczas tworzenia nowej Storyboard po prostu ustaw tę samą nazwę na StoryboardID i dodaj nazwę Storyboard w wyliczeniu „ StoryBoardName ”


0

Zawsze możesz przejść bezpośrednio do kontrolera głównego:

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

0

Poniższe rozszerzenie pozwala załadować plik Storyboardi jest on powiązany UIViewController. Przykład: jeśli masz UIViewControllernazwaną ModalAlertViewControlleri storyboard o nazwie „ModalAlert” np

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

Załaduje zarówno Storyboardi UIViewControlleri vcbędzie typu ModalAlertViewController. Uwaga Zakłada, że ​​identyfikator scenorysu ma taką samą nazwę jak scenorys i że scenariusz został oznaczony jako kontroler widoku początkowego .

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
    }
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.