View controller supporting nested storyboard loading
//
// Copyright © 2013 Yuri Kotov
//
#import "ADVPlaceholderViewController.h"
static void * ObservationContext = &ObservationContext;
@implementation ADVPlaceholderViewController
#pragma mark - NSCoding
- (id) awakeAfterUsingCoder:(NSCoder *)decoder
{
__autoreleasing NSString *identifier;
__autoreleasing NSString *storyboardName;
[self getStoryboard:&storyboardName andIdentifier:&identifier];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:self.nibBundle];
UIViewController *controller = identifier
? [storyboard instantiateViewControllerWithIdentifier:identifier]
: [storyboard instantiateInitialViewController];
NSString *keyPath = NSStringFromSelector(@selector(storyboard));
[controller addObserver:self.observer
forKeyPath:keyPath
options:NSKeyValueObservingOptionOld
context:ObservationContext];
return controller;
}
#pragma mark - NSKeyValueObserving
+ (void) observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if (ObservationContext == context)
{
UIStoryboard *storyboard = change[NSKeyValueChangeOldKey];
[object removeObserver:self.observer forKeyPath:keyPath];
[object setValue:storyboard forKey:keyPath];
}
}
#pragma mark - ADVPlaceholderViewController
- (id) observer
{
return self.class;
}
+ (id) observer
{
return self;
}
- (void) getStoryboard:(NSString **)storyboard andIdentifier:(NSString **)identifier
{
enum NSUInteger { ComponentStoryboard, ComponentIdentifier };
NSArray *components = [self.title componentsSeparatedByString:@"."];
switch (components.count)
{
case 2:
*identifier = components[ComponentIdentifier];
case 1:
*storyboard = components[ComponentStoryboard];
break;
default:
NSAssert(NO, @"Invalid 'title' format");
break;
}
}
@end
//
// Copyright © 2013 Yuri Kotov
//
#import <UIKit/UIKit.h>
@interface ADVPlaceholderViewController : UIViewController
@end