스토리 보드가 사용자 정의 뷰 컨트롤러의 다른 하위 클래스를 인스턴스화하도록하는 것이 가능합니다. 약간 비 정통적인 기술인 alloc
뷰 컨트롤러에 대한 메서드를 재정의해야합니다 . 커스텀 뷰 컨트롤러가 생성되면 오버라이드 된 alloc 메소드는 실제로 alloc
서브 클래스 에서 실행 된 결과를 반환합니다 .
나는 다양한 시나리오에서 테스트했고 오류가 없었지만 더 복잡한 설정에 대처할 수는 없지만 작동하지 않아야 할 이유가 없다는 단서로 대답을 시작해야합니다. . 또한이 방법을 사용하여 앱을 제출하지 않았으므로 Apple의 검토 프로세스에서 거부 될 수있는 외부 기회가 있습니다 (다시 말하지만 그 이유는 알 수 없습니다).
데모 목적으로 UILabel IBOutlet 및 IBAction이있는 UIViewController
called 의 하위 클래스가 TestViewController
있습니다. 내 스토리 보드에서 뷰 컨트롤러를 추가하고 클래스를으로 수정하고 TestViewController
IBOutlet을 UILabel에 연결하고 IBAction을 UIButton에 연결했습니다. 앞의 viewController에서 UIButton에 의해 트리거되는 모달 segue를 통해 TestViewController를 제시합니다.
어떤 클래스가 인스턴스화되는지 제어하기 위해 정적 변수와 관련 클래스 메서드를 추가 했으므로 사용할 서브 클래스를 가져 오거나 설정합니다 (어떤 서브 클래스를 인스턴스화 할 것인지 결정하는 다른 방법을 채택 할 수 있습니다).
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
방법 검사가 어떤 혼동을 피하기 위해, 요구 된 클래스 이름이 실제로 TestViewController의 서브 클래스 있는지 확인합니다. 위의에 대한 참조 BlueTestViewController
는이 기능을 테스트하기위한 것입니다.