Birden çok alt sınıf için tek film şeridi uiviewcontroller nasıl kullanılır


118

UINavigationControllerİlk görünüm denetleyicisini içeren bir storyboard'um olduğunu varsayalım . Onun kökü görünümü kontrolörü arasında alt sınıfıdır UITableViewControllerolan BasicViewController. Bu sahiptir IBActiongezinme çubuğunun sağ navigasyon düğmesinin bağlı olan

ek görsel senaryolar oluşturmak zorunda kalmadan diğer görünümler için şablon olarak film şeridi kullanmak istiyorum Oradan. Diyelim ki bu görünümler tam olarak aynı arabirime sahip olacak, ancak sınıfın kök görünüm denetleyicisine SpecificViewController1ve SpecificViewController2alt sınıfları olan BasicViewController.
Bu 2 görünüm denetleyicisi, IBActionyöntem dışında aynı işlevselliğe ve arayüze sahip olacaktır .
Aşağıdaki gibi olacaktır:

@interface BasicViewController : UITableViewController

@interface SpecificViewController1 : BasicViewController

@interface SpecificViewController2 : BasicViewController

Bunun gibi bir şey yapabilir miyim
Sadece film şeridini başlatabilir miyim, BasicViewControllerancak alt sınıf için kök görünüm denetleyicisine sahip olabilir miyim SpecificViewController1ve SpecificViewController2?

Teşekkürler.


3
Bunu uç ile yapabileceğinizi belirtmekte fayda var. Ancak, yalnızca film şeridinde (örneğin, statik / prototip hücre) bazı güzel özellikler isteyen benim gibiyseniz, o zaman şansımız tükendi demektir.
Joseph Lin

Yanıtlar:


57

harika bir soru - ama ne yazık ki sadece yetersiz bir cevap. Şu anda önerdiğiniz şeyi yapmanın mümkün olduğuna inanmıyorum çünkü UIStoryboard'da, başlatma sırasında film şeridindeki nesne ayrıntılarında tanımlandığı gibi, storyboard ile ilişkili görünüm denetleyicisinin geçersiz kılınmasına izin veren hiçbir başlatıcı yok. Stok tahtasındaki tüm UI öğelerinin, görünüm denetleyicisindeki özelliklerine bağlı olduğu başlangıç ​​aşamasındadır.

Varsayılan olarak, film şeridi tanımında belirtilen görünüm denetleyicisi ile başlatılacaktır.

Film şeridinde oluşturduğunuz UI öğelerini yeniden kullanmaya çalışıyorsanız, görünüm denetleyicisine olaylar hakkında "bilgi verebilmek" için, bunların yine de görünüm denetleyicisinin kullandığı özelliklere bağlı veya ilişkilendirilmiş olması gerekir.

Özellikle sadece 3 görünüm için benzer bir tasarıma ihtiyacınız varsa, bir storyboard düzenini kopyalamak o kadar da önemli değil, ancak bunu yaparsanız, önceki tüm ilişkilerin temizlendiğinden emin olmalısınız, yoksa çalıştığında çökecektir. önceki görünüm denetleyicisiyle iletişim kurmak için. Bunları günlük çıktısında KVO hata mesajları olarak tanıyabileceksiniz.

Alabileceğiniz birkaç yaklaşım:

  • UI öğelerini bir UIView'de - bir xib dosyasında depolayın ve bunu temel sınıfınızdan örnekleyin ve ana görünüme, tipik olarak self.view olmak üzere bir alt görünüm olarak ekleyin. Öyleyse, storyboard düzenini, temelde boş görünüm denetleyicilerinin film şeridinde yerlerini tutan ancak kendilerine atanmış doğru görünüm denetleyicisi alt sınıfıyla kullanırsınız. Tabandan miras alacakları için, bu görüşe sahip olacaklardı.

  • düzeni kodda oluşturun ve temel görünüm denetleyicinizden kurun. Açıkçası bu yaklaşım, film şeridini kullanma amacını ortadan kaldırır, ancak sizin durumunuzda gitmenin yolu olabilir. Uygulamanın film şeridi yaklaşımından yararlanacak başka bölümlerine sahipseniz, uygunsa burada ve orada sapmanızda bir sorun yoktur. Bu durumda, yukarıdaki gibi, yalnızca alt sınıfınız atanmış banka görünümü denetleyicilerini kullanırsınız ve temel görünüm denetleyicisinin kullanıcı arabirimini yüklemesine izin verirsiniz.

Apple, önerdiğiniz şeyi yapmanın bir yolunu bulsaydı iyi olurdu, ancak grafik öğelerinin denetleyici alt sınıfı ile önceden bağlantılı olması sorunu yine de bir sorun olacaktır.

Yeni Yılınız kutlu olsun !! iyi ol


Bu hızlı oldu. Düşündüğüm gibi bu mümkün olmazdı. Şu anda sadece o BasicViewController sınıfına sahip olarak bir çözüm buluyorum ve hangi "sınıf" / "mod" olarak davranacağını gösteren ek özelliğe sahibim. Yine de teşekkürler.
verdy

2
çok kötü :( Sanırım aynı görünüm denetleyicisini kopyalayıp yapıştırmam ve geçici çözüm olarak sınıfını değiştirmem gerekiyor.
Hlung

1
Ve bu yüzden Storyboard'ları sevmiyorum ... bir şekilde standart görünümlerden biraz daha fazlasını
yaptıktan

Bunu söylediğini duymak çok üzücü. Çözüm arıyorum
Tony

2
Başka bir yaklaşım daha var: Farklı temsilcilerde özel mantığı belirtin ve readyForSegue'da doğru temsilciyi atayın. Bu şekilde, Storyboard'da 1 UIViewController + 1 UIViewController oluşturursunuz, ancak birden fazla uygulama sürümünüz vardır.
plam4u

45

Aradığımız satırın kodu:

object_setClass(AnyObject!, AnyClass!)

Storyboard'da -> UIViewController'ı ekleyin ve ona bir ParentVC sınıf adı verin.

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

5
Teşekkürler, sadece işe yarıyor, örneğin: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
Bunun nasıl çalışacağını anladığımdan emin değilim. Ebeveyn, sınıfını bir çocuğunki olarak mı ayarlıyor? O halde nasıl birden çok çocuğunuz olur ?!
user1366265

2
efendim, günümü
jere

2
Pekala çocuklar, biraz daha ayrıntılı olarak açıklamama izin verin: Neyi başarmak istiyoruz? Storyboard'u daha fazla sınıf için kullanabilmemiz için ParentViewController'ımızı alt sınıflara ayırmak istiyoruz. Yani her şeyi yapan sihirli çizgi benim çözümümde vurgulanmıştır ve ParentVC'de awakeFromNib'de kullanılmalıdır. Daha sonra olan şey, alt sınıf haline gelen yeni ayarlanmış ChildVC1'deki tüm yöntemleri kullanmasıdır. Daha fazla ChildVC için kullanmak istiyorsanız? Mantığınızı awakeFromNib'de yapın .. if (type = a) {object_setClass (self, ChildVC1.self)} else {object_setClass (self.ChildVC2.self)} İyi şanslar.
Jiří Zahálka

10
Bunu kullanırken çok dikkatli olun! Normalde bu hiç kullanılmamalıdır ... Bu sadece verilen göstericinin isa göstericisini değiştirir ve örneğin farklı özellikleri barındırmak için belleği yeniden tahsis etmez. Bunun bir göstergesi, işaretçinin selfdeğişmemesidir. Bu nedenle nesnenin incelenmesi (örn. _İvar / özellik değerlerinin okunması) object_setClassçökmelere neden olabilir.
Patrik

15

Kabul edilen yanıtın da belirttiği gibi, hikaye tahtaları ile yapmak mümkün gibi görünmüyor.

Benim çözümüm Nib'leri kullanmak - tıpkı geliştiricilerin hikaye tahtalarından önce kullandığı gibi. Yeniden kullanılabilir, alt sınıflandırılabilir bir görünüm denetleyicisine (veya hatta bir görünüme) sahip olmak istiyorsanız, tavsiyem Nibs'i kullanmaktır.

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

Tüm çıkışlarınızı "Dosya Sahibi" ne bağladığınızda MyViewController.xibUcun hangi sınıf olarak yükleneceğini BELİRTEMİYORSANIZ, yalnızca anahtar / değer çiftlerini belirtmiş olursunuz: " bu görünüm, bu örnek değişken adına bağlanmalıdır ." [SubclassMyViewController alloc] initWithNibName:Başlatma işlemini çağırırken , uçta oluşturduğunuz görünümü " kontrol etmek " için hangi görünüm denetleyicisinin kullanılacağını belirtir .


Şaşırtıcı bir şekilde, ObjC çalışma zamanı kitaplığı sayesinde bunun film şeridi ile mümkün olduğu görülüyor. Cevabımı burada kontrol edin: stackoverflow.com/a/57622836/7183675
Adam Tucholski

9

Bir özel görünüm denetleyicisinin farklı alt sınıflarını örnekleyen bir film şeridine sahip olmak mümkündür, ancak biraz alışılmışın dışında bir teknik içerir: allocgörünüm denetleyicisi için yöntemi geçersiz kılmak . Özel görünüm denetleyicisi oluşturulduğunda, geçersiz kılınan tahsis yöntemi aslında allocalt sınıfta çalışmanın sonucunu döndürür .

Cevabı, çeşitli senaryolarda test etmiş ve hiçbir hata almamış olsam da, daha karmaşık kurulumlarla baş edeceğinden emin olamadığım (ancak çalışmaması için bir neden göremiyorum) şartıyla önsöz etmeliyim. . Ayrıca, bu yöntemi kullanarak herhangi bir uygulama göndermedim, bu nedenle Apple'ın inceleme süreci tarafından reddedilme olasılığı var (yine de neden olması gerektiğini görmüyorum).

Gösteri amaçlı, ben bir alt sınıfı var UIViewControllerdenilen TestViewControllerbir UILabel IBOutlet ve bir IBAction sahiptir. Film şeridime bir görünüm denetleyicisi ekledim ve sınıfını değiştirdim ve TestViewControllerIBOutlet'i bir UILabel'e ve IBAction'ı bir UIButton'a bağladım. TestViewController'ı önceki viewController üzerinde bir UIButton tarafından tetiklenen bir modal segment yoluyla sunuyorum.

Film şeridi resmi

Hangi sınıfın somutlaştırıldığını kontrol etmek için, bir statik değişken ve ilişkili sınıf yöntemleri ekledim, böylece kullanılacak alt sınıfı alın / ayarlayın (sanırım biri hangi alt sınıfın somutlaştırılacağını belirlemenin başka yollarını da benimseyebilir):

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

Testim için iki alt sınıfım var TestViewController: RedTestViewControllerve GreenTestViewController. Alt sınıfların her birinin ek özellikleri vardır ve her bir geçersiz kılmaviewDidLoad görünümün arka plan rengini değiştirmek ve UILabel IBOutlet metnini güncellemek için :

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

Bazı durumlarda TestViewControllerkendini örneklemek isteyebilirim , başka durumlarda RedTestViewControllerveya GreenTestViewController. Önceki görünüm denetleyicisinde, bunu aşağıdaki gibi rastgele yapıyorum:

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"];
}

setClassForStoryBoardYöntemin, herhangi bir karışıklığı önlemek için istenen sınıf adının gerçekten bir TestViewController alt sınıfı olup olmadığını kontrol ettiğini unutmayın . Yukarıdaki referans BlueTestViewController, bu işlevselliği test etmek içindir.


Projede benzer bir şey yaptık, ancak UIViewController'ın ayırma yöntemini geçersiz kılarak harici bir sınıftan tüm geçersiz kılmalarla ilgili tüm bilgileri toplayan bir alt sınıf elde ettik. Mükemmel çalışıyor.
Tim

Bu arada, Apple görüntüleme denetleyicilerini aramayı durdurduğu için bu yöntem daha fazla çalışmayı durdurabilir. Örnek için NSManagedObject sınıfı hiçbir zaman ayırma yöntemini almaz. Apple'ın kodu başka bir yönteme kopyalayabileceğini düşünüyorum: belki + allocManagedObject
Tim

7

Bunu, InstantiateViewControllerWithIdentifier'dan sonra deneyin.

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

sevmek :

SubViewController *vc = [sb instantiateViewControllerWithIdentifier:@"MainViewController"];
[vc setClass:[SubViewController class]];

Lütfen kodunuzun ne yaptığı hakkında bazı yararlı açıklamalar ekleyin.
codeforester

7
Alt sınıftan örnek değişkenler kullanırsanız buna ne olur? Çarpışmayı tahmin ediyorum, çünkü buna uyacak kadar bellek ayrılmış değil. Testlerimde alıyorum EXC_BAD_ACCESS, bu yüzden bunu önermiyorum.
Legoless

1
Alt sınıfta yeni değişkenler eklerseniz bu işe yaramayacaktır. Ve çocuğun initda aranmayacak. Bu tür kısıtlamalar, tüm yaklaşımı kullanılamaz hale getirir.
Al Zonke

6

Özellikle nickgzzjr ve Jiří Zahálka yanıtlarına ve CocoaBob'dan ikincisinin altındaki yoruma dayanarak, OP'nin tam olarak ihtiyacı olanı yapan kısa jenerik yöntem hazırladım. Yalnızca film şeridi adını kontrol etmeniz ve Denetleyicileri Görüntüleyici film şeridi kimliğini kontrol etmeniz gerekir

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
    }

Zorla kaydırmadan (hızlı şerit uyarıları) kaçınmak için seçenekler eklenir, ancak yöntem doğru nesneleri döndürür.


5

Kesinlikle bir alt sınıf olmasa da şunları yapabilirsiniz:

  1. option-Bir kopya oluşturmak için Belge Ana Hatlarında temel sınıf görünüm denetleyicisini sürükleyin
  2. Yeni görünüm denetleyicisi kopyasını film şeridi üzerinde ayrı bir yere taşıyın
  3. Identity Inspector'da Sınıfı alt sınıf görünüm denetleyicisine değiştirin

İşte bir örnek Bloku öğretici ben sınıflara, yazdım ViewControllerile WhiskeyViewController:

yukarıdaki üç adımın animasyonu

Bu, film şeridinde görünüm denetleyicisi alt sınıflarının alt sınıflarını oluşturmanıza olanak tanır. Daha sonra kullanabilirsinizinstantiateViewControllerWithIdentifier: belirli alt sınıflar oluşturmak için .

Bu yaklaşım biraz esnek değildir: film şeridinde temel sınıf denetleyicisine yapılan sonraki değişiklikler alt sınıfa yayılmaz. Eğer bir varsa çok alt sınıflarının diğer çözümlerden biri ile daha iyi olabilir, ama bu bir çimdik yapacak.


11
Bu bir alt sınıf montaj ilişkisi değil, bu sadece bir ViewController'ı kopyalıyor.
Ace Green

1
Bu doğru değil. Sınıfı alt sınıfa değiştirdiğinizde bir alt sınıf olur (3. adım). Ardından, istediğiniz değişiklikleri yapabilir ve alt sınıfınızdaki çıkışlara / eylemlere bağlanabilirsiniz.
Aaron Brager

6
Alt sınıflandırma kavramını anladığını sanmıyorum.
Ace Green

5
"Film şeridinde temel sınıf denetleyicisine yapılan sonraki değişiklikler alt sınıfa yayılmazsa", "alt sınıflandırma" olarak adlandırılmaz. Kopyala ve yapıştır.
superarts.org

Identity Inspector'da seçilen temel sınıf, hala bir alt sınıftır. Başlatılan ve iş mantığını kontrol eden nesne hala bir alt sınıftır. Yalnızca film şeridi dosyasında XML olarak depolanan ve aracılığıyla başlatılan kodlanmış görünüm verileri, initWithCoder:miras alınan bir ilişkiye sahip değildir. Bu tür bir ilişki, film şeridi dosyaları tarafından desteklenmez.
Aaron Brager

4

Objc_setclass yöntemi, bir childvc örneği oluşturmaz. Ancak, childvc'den dışarı çıkarken, childvc'nin tanımını çağırıyor. Childvc için ayrı olarak ayrılmış bellek olmadığından, uygulama çöküyor. Temel denetleyicinin bir örneği vardır, oysa çocuk vc'de yoktur.


2

Görsel senaryo taslaklarına çok güvenmiyorsanız, denetleyici için ayrı bir .xib dosyası oluşturabilirsiniz.

Uygun Dosyanın Sahibini ve çıkışlarını şu şekilde ayarlayın MainViewControllerve geçersiz kılıninit(nibName:bundle:)Çocuklarının aynı Uca ve çıkışlarına erişebilmeleri için Ana VC'ye .

Kodunuz şöyle görünmelidir:

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

Ve Child VC'niz ebeveyninin ucunu yeniden kullanabilecektir:

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

2

Buradan ve oradan yanıtlar alarak bu temiz çözümü buldum.

Bu işlevle bir üst öğe görünümü denetleyicisi oluşturun.

class ParentViewController: UIViewController {


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

        object_setClass(self, T.self)

    }

}

Bu, derleyicinin alt görünüm denetleyicisinin üst görünüm denetleyicisinden devralmasını sağlamasına olanak tanır.

Ardından, bir alt sınıf kullanarak bu denetleyiciye geçiş yapmak istediğinizde şunları yapabilirsiniz:

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

}

İşin güzel yanı, kendisine bir storyboard referansı ekleyebilmeniz ve ardından "sonraki" çocuk görünümü denetleyicisini aramaya devam edebilmenizdir.


1

Muhtemelen en esnek yol, yeniden kullanılabilir görünümler kullanmaktır.

(Ayrı bir XIB dosyasında bir Görünüm oluşturun veya Container viewbunu film şeridindeki her bir alt sınıf görünüm denetleyicisi sahnesine ekleyin)


1
Lütfen olumsuz oy kullandığınızda yorum yapın. Bu soruya doğrudan cevap vermediğimi biliyorum, ancak sorunun köküne bir çözüm öneriyorum.
DanSkeel

1

Basit, açık, günlük bir çözüm var.

Mevcut film şeridini / denetleyiciyi yeni storyobard / denetleyicinin içine koyun. Konteyner görünümü olarak IE.

Bu, denetleyicileri görüntülemek için "alt sınıflandırma" ile tam olarak benzer bir kavramdır.

Her şey tam olarak bir alt sınıfta olduğu gibi çalışır.

Genelde bir görünüm alt görünümünü başka bir görünümün içine koyduğunuz gibi , doğal olarak genellikle başka bir görünüm denetleyicisinin içine bir görünüm denetleyicisi yerleştirirsiniz. .

Bunu başka nasıl yapabilirsin?

Bu, "alt görünüm" kavramı kadar basit, iOS'un temel bir parçasıdır.

Bu kadar kolay ...

/*

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

Şimdi belli ki listne istersen onu yapmak zorundasın

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

vs vs.

Kapsayıcı görünümleri, "alt görünümlerin" "tıpkı" alt sınıflandırma "gibi" olduğu gibi "alt sınıflandırma gibidir.

Tabii ki, "bir düzeni inceleyemezsiniz" - bu ne anlama geliyor?

("Alt sınıflandırma", OO yazılımıyla ilgilidir ve "düzenler" ile bağlantısı yoktur.)

Açıkçası, bir görünümü yeniden kullanmak istediğinizde, onu başka bir görünümde alt görüntülemeniz yeterlidir.

Bir denetleyici düzenini yeniden kullanmak istediğinizde, onu başka bir denetleyicide görüntülemeniz yeterlidir.

Bu, iOS'un en temel mekanizması gibidir !!


Not - yıllardır başka bir görünüm denetleyicisini bir konteyner görünümü olarak dinamik olarak yüklemek önemsizdi. Son bölümde açıklanmıştır: https://stackoverflow.com/a/23403979/294884

Not - "_sb", yazmayı kaydetmek için kullandığımız açık bir makrodur,

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

1

@ Jiří Zahálka'nın ilham verici cevabı için teşekkürler, çözümümü 4 yıl önce burada yanıtladım , ancak @Sayka bir cevap olarak göndermemi önerdi, işte burada.

Projelerimde normalde, bir UIViewController alt sınıfı için Storyboard kullanıyorsam instantiate(), Storyboard'dan kolayca bir örnek oluşturmak için her zaman o alt sınıfta çağrılan statik bir yöntem hazırlarım . Öyleyse, OP'nin sorusunu çözmek için, aynı Storyboard'u farklı alt sınıflar için paylaşmak istiyorsak, setClass()geri vermeden önce o örneğe gidebiliriz .

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

0

Cocoabob'un Jiří Zahálka cevabından yaptığı yorum bu çözümü elde etmeme yardımcı oldu ve iyi çalıştı.

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);
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.