Cara menggunakan pengontrol uiview papan cerita tunggal untuk beberapa subclass

118

Katakanlah saya memiliki storyboard yang berisi UINavigationControllersebagai pengontrol tampilan awal. Pengontrol tampilan akarnya adalah subkelas UITableViewController, yaitu BasicViewController. Itu memiliki IBActionyang terhubung ke tombol navigasi kanan dari bilah navigasi

Dari sana saya ingin menggunakan storyboard sebagai template untuk tampilan lain tanpa harus membuat storyboard tambahan. Katakanlah tampilan ini akan memiliki antarmuka yang persis sama tetapi dengan pengontrol tampilan root dari kelas SpecificViewController1dan SpecificViewController2yang merupakan subkelas dari BasicViewController.
Kedua pengontrol tampilan tersebut akan memiliki fungsionalitas dan antarmuka yang sama kecuali untuk IBActionmetode.
Ini akan menjadi seperti berikut:

@interface BasicViewController : UITableViewController

@interface SpecificViewController1 : BasicViewController

@interface SpecificViewController2 : BasicViewController

Bisakah saya melakukan sesuatu seperti itu?
Bisakah saya membuat instance storyboard BasicViewControllertetapi memiliki pengontrol tampilan root ke subkelas SpecificViewController1dan SpecificViewController2?

Terima kasih.

verdy
sumber
3
Mungkin perlu diketahui bahwa Anda dapat melakukan ini dengan ujung pena. Tetapi jika Anda seperti saya yang menginginkan beberapa fitur bagus yang hanya dimiliki storyboard (sel statis / prototipe, misalnya), maka saya kira kami kurang beruntung.
Joseph Lin

Jawaban:

57

pertanyaan bagus - tapi sayangnya hanya jawaban yang timpang. Saya tidak percaya bahwa saat ini mungkin untuk melakukan apa yang Anda usulkan karena tidak ada penginisialisasi di UIStoryboard yang memungkinkan penggantian pengontrol tampilan yang terkait dengan storyboard seperti yang ditentukan dalam detail objek di storyboard saat inisialisasi. Pada inisialisasi semua elemen UI di stoaryboard ditautkan ke propertinya di pengontrol tampilan.

Ini akan secara default diinisialisasi dengan pengontrol tampilan yang ditentukan dalam definisi storyboard.

Jika Anda mencoba untuk mendapatkan kembali elemen UI yang Anda buat di storyboard, mereka masih harus ditautkan atau dikaitkan ke properti yang pernah digunakan pengontrol tampilan agar dapat "memberi tahu" pengontrol tampilan tentang peristiwa.

Ini bukan masalah besar menyalin tata letak storyboard terutama jika Anda hanya memerlukan desain yang serupa untuk 3 tampilan, namun jika Anda melakukannya, Anda harus memastikan bahwa semua asosiasi sebelumnya dihapus, atau akan mengalami crash saat mencoba untuk berkomunikasi dengan pengontrol tampilan sebelumnya. Anda akan dapat mengenalinya sebagai pesan kesalahan KVO di keluaran log.

Beberapa pendekatan yang dapat Anda lakukan:

  • simpan elemen UI dalam UIView - dalam file xib dan buat instance dari kelas dasar Anda dan tambahkan sebagai sub tampilan di tampilan utama, biasanya self.view. Kemudian Anda cukup menggunakan tata letak storyboard dengan pengontrol tampilan yang pada dasarnya kosong memegang tempatnya di storyboard tetapi dengan sub kelas pengontrol tampilan yang ditetapkan untuk mereka. Karena mereka akan mewarisi dari pangkalan, mereka akan mendapatkan pandangan itu.

  • buat tata letak dalam kode dan instal dari pengontrol tampilan dasar Anda. Jelas pendekatan ini mengalahkan tujuan penggunaan storyboard, tetapi mungkin cara yang tepat untuk kasus Anda. Jika Anda memiliki bagian lain dari aplikasi yang akan mendapat manfaat dari pendekatan papan cerita, tidak apa-apa untuk menyimpang di sana-sini jika perlu. Dalam kasus ini, seperti di atas, Anda hanya akan menggunakan pengontrol tampilan bank dengan subkelas Anda ditetapkan dan membiarkan pengontrol tampilan dasar menginstal UI.

Akan lebih baik jika Apple menemukan cara untuk melakukan apa yang Anda usulkan, tetapi masalah memiliki elemen grafis yang telah ditautkan sebelumnya dengan subkelas pengontrol masih akan menjadi masalah.

Selamat tahun baru!! dengan baik

CocoaEv
sumber
Itu tadi cepat. Sudah kuduga, itu tidak mungkin. Saat ini saya datang dengan solusi dengan hanya memiliki kelas BasicViewController dan memiliki properti tambahan untuk menunjukkan "kelas" / "mode" mana yang akan bertindak sebagai. Terima kasih.
verdy
2
terlalu buruk :( Sepertinya saya harus menyalin dan menempel pengontrol tampilan yang sama dan mengubah kelasnya sebagai solusi.
Hlung
1
Dan inilah mengapa saya tidak suka Storyboard ... entah bagaimana mereka tidak benar-benar berfungsi setelah Anda melakukan lebih dari tampilan standar ...
TheEye
Sedih sekali saat mendengar kamu mengatakan itu. Saya mencari solusi
Tony
2
Ada pendekatan lain: Tentukan logika kustom di delegasi yang berbeda dan di preparedForSegue, tetapkan delegasi yang benar. Dengan cara ini, Anda membuat 1 UIViewController + 1 UIViewController di Storyboard tetapi Anda memiliki beberapa versi implementasi.
plam4u
45

Kode baris yang kita cari adalah:

object_setClass(AnyObject!, AnyClass!)

Di Storyboard -> tambahkan UIViewController berikan nama kelas ParentVC.

class ParentVC: UIViewController {

    var type: Int?

    override func awakeFromNib() {

        if type = 0 {

            object_setClass(self, ChildVC1.self)
        }
        if type = 1 {

            object_setClass(self, ChildVC2.self)
        }  
    }

    override func viewDidLoad() {   }
}

class ChildVC1: ParentVC {

    override func viewDidLoad() {
        super.viewDidLoad()

        println(type)
        // Console prints out 0
    }
}

class ChildVC2: ParentVC {

    override func viewDidLoad() {
        super.viewDidLoad()

        println(type)
        // Console prints out 1
    }
}
Jiří Zahálka
sumber
5
Terima kasih, ini berfungsi, misalnya:class func instantiate() -> SubClass { let instance = (UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("SuperClass") as? SuperClass)! object_setClass(instance, SubClass.self) return (instance as? SubClass)! }
CocoaBob
3
Saya tidak yakin saya mengerti bagaimana ini seharusnya bekerja. Orang tua menyetel kelasnya sebagai kelas anak? Bagaimana Anda bisa memiliki banyak anak ?!
pengguna1366265
2
Anda tuan, telah membuat hari saya menyenangkan
jere
2
Oke teman-teman, jadi izinkan saya menjelaskannya sedikit lebih detail: Apa yang ingin kita capai? Kami ingin membuat subkelas ParentViewController kami sehingga kami dapat menggunakan Storyboardnya untuk lebih banyak kelas. Jadi garis ajaib yang melakukan semuanya disorot dalam solusi saya dan harus digunakan di awakeFromNib di ParentVC. Apa yang terjadi kemudian adalah bahwa ia menggunakan semua metode dari ChildVC1 yang baru ditetapkan yang menjadi subclass. Jika Anda ingin menggunakannya untuk lebih banyak ChildVC? Cukup lakukan logika Anda di awakeFromNib .. if (type = a) {object_setClass (self, ChildVC1.self)} else {object_setClass (self.ChildVC2.self)} Selamat mencoba.
Jiří Zahálka
10
Berhati-hatilah saat menggunakan ini! Biasanya ini tidak boleh digunakan sama sekali ... Ini hanya mengubah isa pointer dari pointer yang diberikan dan tidak mengalokasikan kembali memori untuk mengakomodasi misalnya properti yang berbeda. Salah satu indikatornya adalah penunjuk ke selftidak berubah. Jadi pemeriksaan objek (misalnya membaca _ivar / nilai properti) setelahnya object_setClassdapat menyebabkan crash.
Patrik
15

Seperti yang dinyatakan oleh jawaban yang diterima, sepertinya tidak mungkin dilakukan dengan papan cerita.

Solusi saya adalah menggunakan Nib - sama seperti dev yang menggunakannya sebelum storyboard. Jika Anda ingin memiliki pengontrol tampilan yang dapat digunakan kembali, subclassable (atau bahkan tampilan), rekomendasi saya adalah menggunakan Nibs.

SubclassMyViewController *myViewController = [[SubclassMyViewController alloc] initWithNibName:@"MyViewController" bundle:nil]; 

Ketika Anda menghubungkan semua outlet Anda ke "Pemilik File" di MyViewController.xibAnda TIDAK menentukan kelas Nib apa yang harus dimuat, Anda hanya menentukan pasangan kunci-nilai: " tampilan ini harus terhubung ke nama variabel instance ini ." Saat memanggil [SubclassMyViewController alloc] initWithNibName:proses inisialisasi menentukan pengontrol tampilan apa yang akan digunakan untuk " mengontrol " tampilan yang Anda buat di ujung pena.

kgaidis
sumber
Anehnya, hal ini dimungkinkan dengan storyboard, berkat perpustakaan runtime ObjC. Periksa jawaban saya di sini: stackoverflow.com/a/57622836/7183675
Adam Tucholski
9

Storyboard dapat membuat instance subclass berbeda dari pengontrol tampilan kustom, meskipun ini melibatkan teknik yang sedikit tidak ortodoks: mengganti allocmetode untuk pengontrol tampilan. Saat pengontrol tampilan kustom dibuat, metode alokasi yang diganti sebenarnya mengembalikan hasil dari berjalan allocpada subkelas.

Saya harus mengawali jawaban dengan syarat bahwa, meskipun saya telah mengujinya dalam berbagai skenario dan tidak menerima kesalahan, saya tidak dapat memastikan bahwa itu akan mengatasi pengaturan yang lebih kompleks (tetapi saya tidak melihat alasan mengapa tidak berfungsi) . Juga, saya belum mengirimkan aplikasi apa pun menggunakan metode ini, jadi ada kemungkinan luar bahwa itu mungkin ditolak oleh proses peninjauan Apple (meski sekali lagi saya tidak melihat alasan mengapa harus).

Untuk tujuan demonstrasi, saya memiliki subkelas yang UIViewControllerdisebut TestViewController, yang memiliki IBOutlet UILabel, dan IBAction. Di storyboard saya, saya telah menambahkan pengontrol tampilan dan mengubah kelasnya menjadi TestViewController, dan menghubungkan IBOutlet ke UILabel dan IBAction ke UIButton. Saya menyajikan TestViewController melalui segue modal yang dipicu oleh UIButton pada viewController sebelumnya.

Gambar papan cerita

Untuk mengontrol kelas mana yang dipakai, saya telah menambahkan variabel statis dan metode kelas terkait jadi dapatkan / setel subkelas yang akan digunakan (saya kira seseorang dapat mengadopsi cara lain untuk menentukan subkelas mana yang akan dipakai):

TestViewController.m:

#import "TestViewController.h"

@interface TestViewController ()
@end

@implementation TestViewController

static NSString *_classForStoryboard;

+(NSString *)classForStoryboard {
    return [_classForStoryboard copy];
}

+(void)setClassForStoryBoard:(NSString *)classString {
    if ([NSClassFromString(classString) isSubclassOfClass:[self class]]) {
        _classForStoryboard = [classString copy];
    } else {
        NSLog(@"Warning: %@ is not a subclass of %@, reverting to base class", classString, NSStringFromClass([self class]));
        _classForStoryboard = nil;
    }
}

+(instancetype)alloc {
    if (_classForStoryboard == nil) {
        return [super alloc];
    } else {
        if (NSClassFromString(_classForStoryboard) != [self class]) {
            TestViewController *subclassedVC = [NSClassFromString(_classForStoryboard) alloc];
            return subclassedVC;
        } else {
            return [super alloc];
        }
    }
}

Untuk pengujian saya, saya memiliki dua subclass dari TestViewController: RedTestViewControllerdan GreenTestViewController. Masing-masing subclass memiliki properti tambahan dan masing-masing mengganti viewDidLoaduntuk mengubah warna latar belakang tampilan dan memperbarui teks UILabel IBOutlet:

RedTestViewController.m:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    self.view.backgroundColor = [UIColor redColor];
    self.testLabel.text = @"Set by RedTestVC";
}

GreenTestViewController.m:

- (void)viewDidLoad {
    [super viewDidLoad];

    self.view.backgroundColor = [UIColor greenColor];
    self.testLabel.text = @"Set by GreenTestVC";
}

Pada beberapa kesempatan saya mungkin ingin membuat contoh TestViewControllersendiri, pada kesempatan lain RedTestViewControlleratau GreenTestViewController. Di pengontrol tampilan sebelumnya, saya melakukan ini secara acak sebagai berikut:

NSInteger vcIndex = arc4random_uniform(4);
if (vcIndex == 0) {
    NSLog(@"Chose TestVC");
    [TestViewController setClassForStoryBoard:@"TestViewController"];
} else if (vcIndex == 1) {
    NSLog(@"Chose RedVC");
    [TestViewController setClassForStoryBoard:@"RedTestViewController"];
} else if (vcIndex == 2) {
    NSLog(@"Chose BlueVC");
    [TestViewController setClassForStoryBoard:@"BlueTestViewController"];
} else {
    NSLog(@"Chose GreenVC");
    [TestViewController setClassForStoryBoard:@"GreenTestViewController"];
}

Perhatikan bahwa setClassForStoryBoardmetode ini memeriksa untuk memastikan bahwa nama kelas yang diminta memang merupakan subkelas TestViewController, untuk menghindari campur-aduk. Referensi di atas BlueTestViewControlleruntuk menguji fungsionalitas ini.

pbasdf
sumber
Kami telah melakukan sesuatu yang serupa dalam proyek ini, tetapi menimpa metode alokasi UIViewController untuk mendapatkan subkelas dari kelas eksternal yang mengumpulkan info lengkap tentang semua penggantian. Bekerja dengan sempurna.
Tim
Ngomong-ngomong, metode ini mungkin berhenti berfungsi sebagaimana mestinya karena Apple berhenti memanggil alokasi pada pengontrol tampilan. Misalnya, kelas NSManagedObject tidak pernah menerima metode alokasi. Saya pikir Apple dapat menyalin kode ke metode lain: mungkin + alokasiManagedObject
Tim
7

coba ini, setelah instantiateViewControllerWithIdentifier.

- (void)setClass:(Class)c {
    object_setClass(self, c);
}

Suka :

SubViewController *vc = [sb instantiateViewControllerWithIdentifier:@"MainViewController"];
[vc setClass:[SubViewController class]];
莫 振华
sumber
Tambahkan beberapa penjelasan bermanfaat tentang fungsi kode Anda.
codeforester
7
Apa yang terjadi dengan ini, jika Anda menggunakan variabel instan dari subclass? Saya menduga crash, karena tidak ada cukup memori yang dialokasikan untuk menyesuaikan itu. Dalam tes saya, saya sudah mendapatkan EXC_BAD_ACCESS, jadi tidak merekomendasikan ini.
Tanpa kaki
1
Ini tidak akan berhasil jika Anda menambahkan variabel baru di kelas anak. Dan anak initjuga tidak akan dipanggil. Batasan seperti itu membuat semua pendekatan tidak dapat digunakan.
Al Zonke
6

Mendasarkan terutama pada jawaban nickgzzjr dan Jiří Zahálka ditambah komentar di bawah yang kedua dari CocoaBob, saya telah menyiapkan metode umum singkat yang melakukan persis apa yang dibutuhkan OP. Anda hanya perlu memeriksa nama storyboard dan ID storyboard View Controllers

class func instantiate<T: BasicViewController>(as _: T.Type) -> T? {
        let storyboard = UIStoryboard(name: "StoryboardName", bundle: nil)
        guard let instance = storyboard.instantiateViewController(withIdentifier: "Identifier") as? BasicViewController else {
            return nil
        }
        object_setClass(instance, T.self)
        return instance as? T
    }

Opsional ditambahkan untuk menghindari pembongkaran paksa (peringatan swiftlint), tetapi metode mengembalikan objek yang benar.

Adam Tucholski
sumber
5

Meskipun ini bukan subkelas, Anda dapat:

  1. option-menarik pengontrol tampilan kelas dasar di Garis Besar Dokumen untuk membuat salinan
  2. Pindahkan salinan pengontrol tampilan baru ke tempat terpisah di storyboard
  3. Ubah Kelas ke pengontrol tampilan subkelas di Inspektur Identitas

Berikut adalah contoh dari tutorial Bloc yang saya tulis, ViewControllerdengan subclassing WhiskeyViewController:

animasi dari tiga langkah di atas

Ini memungkinkan Anda membuat subkelas dari subkelas pengontrol tampilan di storyboard. Anda kemudian dapat menggunakan instantiateViewControllerWithIdentifier:untuk membuat subclass tertentu.

Pendekatan ini agak tidak fleksibel: modifikasi selanjutnya dalam storyboard ke pengontrol kelas dasar tidak menyebar ke subkelas. Jika Anda memiliki banyak subclass, Anda mungkin lebih baik menggunakan salah satu solusi lain, tetapi ini akan dilakukan dalam keadaan darurat.

Aaron Brager
sumber
11
Ini bukan teman subclass, ini hanya menduplikasi ViewController.
Ace Green
1
Itu tidak benar. Ini menjadi subkelas saat Anda mengubah Kelas menjadi subkelas (langkah 3). Kemudian Anda dapat membuat perubahan apa pun yang Anda inginkan, dan terhubung ke outlet / tindakan di subkelas Anda.
Aaron Brager
6
Saya tidak berpikir Anda mendapatkan konsep subclassing.
Ace Green
5
Jika "modifikasi selanjutnya dalam storyboard ke pengontrol kelas dasar tidak menyebar ke subkelas", itu tidak disebut "subkelas". Ini salin & tempel.
superarts.org
Kelas yang mendasari, yang dipilih di Inspektur Identitas, masih merupakan subkelas. Objek yang diinisialisasi dan mengontrol logika bisnis masih merupakan subkelas. Hanya data tampilan yang dienkode, yang disimpan sebagai XML dalam file storyboard dan diinisialisasi melalui initWithCoder:, tidak memiliki hubungan yang diwariskan. Jenis hubungan ini tidak didukung oleh file storyboard.
Aaron Brager
4

Metode Objc_setclass tidak membuat turunan dari childvc. Tapi saat muncul dari childvc, deinit dari childvc sedang dipanggil. Karena tidak ada memori yang dialokasikan secara terpisah untuk childvc, aplikasi macet. Pengontrol dasar memiliki sebuah instance, sedangkan anak vc tidak memiliki.

pengguna8044830
sumber
2

Jika Anda tidak terlalu bergantung pada storyboard, Anda dapat membuat file .xib terpisah untuk pengontrol.

Atur Pemilik File dan outlet yang sesuai ke MainViewControllerdan timpa init(nibName:bundle:)di VC Utama sehingga anak-anaknya dapat mengakses Nib dan outletnya yang sama.

Kode Anda akan terlihat seperti ini:

class MainViewController: UIViewController {
    @IBOutlet weak var button: UIButton!

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: "MainViewController", bundle: nil)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        button.tintColor = .red
    }
}

Dan Child VC Anda akan dapat menggunakan kembali ujung pena orang tuanya:

class ChildViewController: MainViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        button.tintColor = .blue
    }
}
nitrogen
sumber
2

Mengambil jawaban dari sana-sini, saya menemukan solusi yang rapi ini.

Buat pengontrol tampilan orang tua dengan fungsi ini.

class ParentViewController: UIViewController {


    func convert<T: ParentViewController>(to _: T.Type) {

        object_setClass(self, T.self)

    }

}

Hal ini memungkinkan compiler untuk memastikan bahwa pengontrol tampilan anak mewarisi dari pengontrol tampilan induk.

Kemudian kapan pun Anda ingin beralih ke pengontrol ini menggunakan sub kelas, Anda dapat melakukan:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    super.prepare(for: segue, sender: sender)

    if let parentViewController = segue.destination as? ParentViewController {
        ParentViewController.convert(to: ChildViewController.self)
    }

}

Bagian kerennya adalah Anda bisa menambahkan referensi storyboard ke dirinya sendiri, lalu terus memanggil pengontrol tampilan anak "berikutnya".

nickgzzjr.dll
sumber
1

Mungkin cara paling fleksibel adalah menggunakan tampilan yang dapat digunakan kembali.

(Buat Tampilan dalam file XIB terpisah atau Container viewdan tambahkan ke setiap adegan pengontrol tampilan subkelas di storyboard)

DanSkeel
sumber
1
Tolong beri komentar saat Anda memberi suara negatif. Saya tahu bahwa saya tidak menjawab secara langsung pertanyaan itu tetapi saya mengusulkan solusi untuk akar masalah.
DanSkeel
1

Ada solusi sehari-hari yang sederhana dan jelas.

Cukup letakkan storyboard / pengontrol yang ada di dalam storyobard / pengontrol baru. IE sebagai tampilan kontainer.

Ini adalah konsep yang sama persis dengan "subclassing", untuk, pengontrol tampilan.

Semuanya bekerja persis seperti di subclass.

Sama seperti Anda biasanya menempatkan subview tampilan di dalam tampilan lain , biasanya Anda biasanya menempatkan pengontrol tampilan di dalam pengontrol tampilan lain .

Bagaimana lagi Anda bisa melakukannya?

Ini adalah bagian dasar dari iOS, sesederhana konsep "subview".

Semudah ini ...

/*

Search screen is just a modification of our List screen.

*/

import UIKit

class Search: UIViewController {
    
    var list: List!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        list = (_sb("List") as! List
        addChild(list)
        view.addSubview(list.view)
        list.view.bindEdgesToSuperview()
        list.didMove(toParent: self)
    }
}

Anda sekarang jelas harus listmelakukan apa pun yang Anda inginkan

list.mode = .blah
list.tableview.reloadData()
list.heading = 'Search!'
list.searchBar.isHidden = false

dll.

Tampilan penampung "seperti" membuat subkelas dengan cara yang sama seperti "sub-tampilan" adalah "seperti" subkelas.

Tentu saja jelas, Anda tidak bisa "menyubkass sebuah layout" - apa artinya itu?

("Subclassing" berhubungan dengan perangkat lunak OO dan tidak memiliki koneksi ke "tata letak".)

Tentunya saat Anda ingin menggunakan kembali tampilan, Anda cukup men-subviewnya di dalam tampilan lain.

Saat Anda ingin menggunakan kembali tata letak pengontrol, Anda hanya perlu menampilkannya di dalam pengontrol lain.

Ini seperti mekanisme paling dasar dari iOS !!


Catatan - selama bertahun-tahun sekarang sangatlah mudah untuk secara dinamis memuat pengontrol tampilan lain sebagai tampilan penampung. Dijelaskan di bagian terakhir: https://stackoverflow.com/a/23403979/294884

Catatan - "_sb" hanyalah makro yang kami gunakan untuk menyimpan pengetikan,

func _sb(_ s: String)->UIViewController {
    // by convention, for a screen "SomeScreen.storyboard" the
    // storyboardID must be SomeScreenID
    return UIStoryboard(name: s, bundle: nil)
       .instantiateViewController(withIdentifier: s + "ID")
}
Gendut
sumber
1

Terima kasih atas jawaban inspiratif @ Jiří Zahálka, saya menjawab solusi saya 4 tahun yang lalu di sini , tetapi @Sayka menyarankan saya untuk mempostingnya sebagai jawaban, jadi ini dia.

Dalam proyek saya, biasanya, jika saya menggunakan Storyboard untuk subkelas UIViewController, saya selalu menyiapkan metode statis yang disebut instantiate()dalam subkelas itu, untuk membuat instance dari Storyboard dengan mudah. Jadi untuk menjawab pertanyaan OP, jika kita ingin berbagi Storyboard yang sama untuk subclass yang berbeda, kita bisa langsung setClass()ke contoh itu sebelum mengembalikannya.

class func instantiate() -> SubClass {
    let instance = (UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("SuperClass") as? SuperClass)!
    object_setClass(instance, SubClass.self)
    return (instance as? SubClass)!
}
CocoaBob
sumber
0

Komentar Cocoabob dari jawaban Jiří Zahálka membantu saya mendapatkan solusi ini dan berhasil dengan baik.

func openChildA() {
    let storyboard = UIStoryboard(name: "Main", bundle: nil);
    let parentController = storyboard
        .instantiateViewController(withIdentifier: "ParentStoryboardID") 
        as! ParentClass;
    object_setClass(parentController, ChildA.self)
    self.present(parentController, animated: true, completion: nil);
}
Sayka
sumber