Bagaimana saya bisa memuat storyboard secara terprogram dari kelas?

183

Masalah saya adalah saya mencari cara untuk menggunakan storyboard dan xib . Tetapi saya tidak dapat menemukan cara yang tepat untuk memuat dan menampilkan storyboard secara terprogram. Project mulai dikembangkan dengan xib, dan sekarang sangat sulit untuk menyarangkan semua file xib di storyboard. Jadi saya mencari cara untuk melakukannya dalam kode, seperti dengan alloc, init, pushuntuk viewControllers. Dalam kasus saya, saya hanya memiliki satu pengontrol di storyboard:, UITableViewControlleryang memiliki sel statis dengan beberapa konten yang ingin saya tampilkan. Jika ada yang tahu cara yang tepat untuk bekerja dengan xib dan storyboard tanpa refactoring besar, saya akan menghargai bantuannya.

kokoko
sumber

Jawaban:

370

Di storyboard Anda, pergi ke inspektur Atribut dan atur Identifier pengontrol tampilan. Anda kemudian dapat menampilkan pengontrol tampilan menggunakan kode berikut.

UIStoryboard *sb = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:@"myViewController"];
vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:vc animated:YES completion:NULL];
James Beith
sumber
65
[sb instantiateInitialViewController]berguna jika Anda ingin memulai pada pengontrol tampilan default adegan.
drewish
James, terima kasih! Saya telah mencari beberapa waktu untuk mencari cara bagaimana membuat tampilan Storyboard. Jawaban Anda (dan pertanyaan kokoko) paling menyegarkan untuk ditemukan.
bejonbee
Pada kode James Beith, seseorang harus menggunakan kembali UIViewControler * vc jika diaktifkan dan diubah dengan viewcontroller saat ini. Saya menemukan cara yang sulit bahwa vc bertahan dan ditransfer ke storyboard nib sampai pengguna menekan tombol pada tampilan baru, dan sekarang ada kebocoran memori dengan vc yang dibuang dari mantra sebelumnya dari kode ini.
SWoo
11
Jika ada yang ingin tahu bagaimana melakukan ini dalam delegasi aplikasi, Anda mengganti [self presentViewcontroller]logika dengan baris-baris ini dalam urutan sebagai berikut: 1) self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];2) self.window.rootViewController = vc;dan 3) [self.window makeKeyAndVisible];. Anda juga mungkin bisa menghilangkan modalTransitionStylegaris karena ini bukan transisi modal dari delegasi aplikasi.
lewiguez
FYI, jika Anda ingin "mendorong" storyboard baru alih-alih bermunculan secara modern, lihat jawaban chaithraVeeresh.
Adam Johns
76

Cepat 3

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

Cepat 2

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

Prasyarat

Tetapkan Storyboard ID ke pengontrol tampilan Anda.

ID Storyboard

IB> Tunjukkan inspektur Identitas> Identitas> Storyboard ID

Swift (warisan)

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

Sunting: Swift 2 disarankan dalam komentar oleh Fred A.

jika Anda ingin menggunakan tanpa navigationController, Anda harus menggunakan seperti berikut:

    let Storyboard  = UIStoryboard(name: "Main", bundle: nil)
    let vc = Storyboard.instantiateViewController(withIdentifier: "viewController")
    present(vc , animated: true , completion: nil)
Arsitektur Swift
sumber
1
Di Swift 2, Anda tidak perlu menambahkan "as? UIViewController", kompilator menentukannya secara otomatis
Frédéric Adda
2
atau Anda bisa melakukan self.storyboarddan menggabungkan line1 & 2
Honey
17

Atribut inspector memberikan pengidentifikasi untuk tampilan controller dan kode di bawah ini berfungsi untuk saya

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

Coba ini

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

[[UIApplication sharedApplication].keyWindow setRootViewController:vc];
Adetiloye Philip Kehinde
sumber
Gunakan ini jika Anda tidak menggunakan UINavigationController seperti yang ditunjukkan pada jawaban lain
latenitecoder
2

di
NavigationController cepat dan pushController Anda dapat menggantikan

present(vc, animated:true , completion: nil)
Tarik
sumber
1

Untuk swift 3 dan 4 , Anda dapat melakukan ini. Praktik yang baik adalah menetapkan nama Storyboard sama dengan 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)
   }
}

dan kemudian Anda dapat memuat Storyboard Anda di ViewController Anda seperti ini:

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

}

Saat Anda membuat Storyboard baru, atur nama yang sama di StoryboardID dan tambahkan nama Storyboard di enum Anda " StoryBoardName "

Gandhi Mena
sumber
0

Anda selalu dapat melompat langsung ke pengontrol root:

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

Ekstensi di bawah ini memungkinkan Anda untuk memuat Storyboarddan dikaitkan UIViewController. Contoh: Jika Anda memiliki UIViewControllernama ModalAlertViewControllerdan papan cerita bernama "ModalAlert" misalnya

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

Akan memuat keduanya Storyboarddan UIViewControllerdan vcakan bertipe ModalAlertViewController. Catatan Mengasumsikan bahwa Storyboard ID Storyboard memiliki nama yang sama dengan storyboard dan storyboard telah ditandai sebagai 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
    }
}
Norman
sumber