एक स्टोरीबोर्ड को कस्टम व्यू कंट्रोलर के अलग-अलग उपवर्गों में इंस्टेंट करना संभव है, हालांकि इसमें थोड़ी अपरंपरागत तकनीक शामिल है: alloc
व्यू कंट्रोलर के लिए विधि को ओवरराइड करना । जब कस्टम दृश्य नियंत्रक बनाया जाता है, तो ओवरराइड आवंटित विधि वास्तव alloc
में उपवर्ग पर चलने का परिणाम देता है ।
मुझे उत्तर को अनंतिम रूप से प्रस्तुत करना चाहिए, हालांकि मैंने इसे विभिन्न परिदृश्यों में परीक्षण किया है और कोई त्रुटि नहीं मिली है, मैं यह सुनिश्चित नहीं कर सकता कि यह अधिक जटिल सेट अप के साथ सामना करेगा (लेकिन मुझे कोई कारण नहीं है कि यह काम क्यों नहीं करना चाहिए) । इसके अलावा, मैंने इस पद्धति का उपयोग करके कोई भी एप्लिकेशन सबमिट नहीं किया है, इसलिए बाहर का मौका है कि इसे Apple की समीक्षा प्रक्रिया द्वारा अस्वीकार किया जा सकता है (हालांकि फिर से मुझे कोई कारण नहीं दिखाई देना चाहिए कि यह क्यों होना चाहिए)।
प्रदर्शन प्रयोजनों के लिए, मेरे पास उप UIViewController
नाम का एक उपवर्ग है TestViewController
, जिसमें एक UILabel IBOutlet और एक IBAction है। अपने स्टोरीबोर्ड में, मैंने एक दृश्य नियंत्रक जोड़ा है और अपनी कक्षा में संशोधन किया है TestViewController
, और IBOutlet को एक UILabel और IBAction को एक UIButton तक झुका दिया है। मैं TestViewController को पूर्ववर्ती दृश्य नियंत्रण रेखा पर एक UIButton द्वारा ट्रिगर किए गए एक मोडल सेग के माध्यम से प्रस्तुत करता हूं।
यह नियंत्रित करने के लिए कि कौन सी कक्षा में त्वरित किया गया है, मैंने एक स्थिर चर और संबद्ध वर्ग विधियाँ जोड़ी हैं, ताकि उपयोग होने के लिए उप-वर्ग प्राप्त करें / निर्धारित करें (मुझे लगता है कि कोई निर्धारित करने के अन्य तरीके अपना सकता है कि उपवर्ग को तत्काल बनाया जाए):
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];
}
}
}
मेरे परीक्षण के लिए मेरे पास दो उपवर्ग हैं TestViewController
: RedTestViewController
और GreenTestViewController
। उपवर्गों में प्रत्येक के पास अतिरिक्त गुण होते हैं और प्रत्येक ओवरराइड viewDidLoad
दृश्य की पृष्ठभूमि के रंग को बदलने और 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";
}
कुछ मौकों पर मैं TestViewController
खुद को, दूसरे मौकों पर RedTestViewController
या खुद को इंस्टेंट करना चाहूंगा GreenTestViewController
। पूर्ववर्ती दृश्य नियंत्रक में, मैं यादृच्छिक रूप से निम्नानुसार करता हूं:
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"];
}
ध्यान दें कि setClassForStoryBoard
विधि यह सुनिश्चित करने के लिए जांच करती है कि अनुरोधित वर्ग नाम वास्तव में किसी भी मिश्रण-अप से बचने के लिए टेस्टव्यूकंट्रोलर का उपवर्ग है। BlueTestViewController
इस कार्यक्षमता का परीक्षण करने के लिए ऊपर संदर्भ है ।