我研究了大黄建议的RBStoryboardLink方法。该实现替代了看起来很奇怪的视图控制器的属性。我相信我已经找到避免这种情况的方法。这是演示项目。
导航控制器
导航控制器可以只将引用的视图控制器设置为根。这种视图控制器的实现可能如下所示:
@interface ExternNavigationController : UINavigationController
@property (strong, nonatomic) NSString *storyboardName;
@property (strong, nonatomic) NSString *sceneIdentifier;
@end
@implementation ExternNavigationController
- (void)awakeFromNib
{
NSAssert(self.storyboardName, @"storyboardName is required");
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:self.storyboardName bundle:nil];
UIViewController *vc = self.sceneIdentifier
? [storyboard instantiateViewControllerWithIdentifier:self.sceneIdentifier]
: [storyboard instantiateInitialViewController];
self.viewControllers = @[vc];
}
@end
查看控制器
当您要推送外部情节提要板中定义的视图控制器时,问题就开始了。复制属性时就是这种情况。取而代之的是,我们可以实现自定义segue,它将用外部情节提要中的真实目标控制器代替伪造的目标控制器。
@interface ExternStoryboardSegue : UIStoryboardSegue
@end
@implementation ExternStoryboardSegue
- (id)initWithIdentifier:(NSString *)identifier source:(UIViewController *)source destination:(ExternViewController *)destination
{
NSAssert(destination.storyboardName, @"storyboardName is required");
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:destination.storyboardName bundle:nil];
UIViewController *vc = destination.sceneIdentifier
? [storyboard instantiateViewControllerWithIdentifier:destination.sceneIdentifier]
: [storyboard instantiateInitialViewController];
return [super initWithIdentifier:identifier source:source destination:vc];
}
- (void)perform
{
[[self.sourceViewController navigationController] pushViewController:self.destinationViewController animated:YES];
}
@end
ExternViewController用作占位符,并包含替代属性(storyboardName和sceneIdentifier)所需。
@interface ExternViewController : UIViewController
@property (strong, nonatomic) NSString *storyboardName;
@property (strong, nonatomic) NSString *sceneIdentifier;
@end
@implementation ExternViewController
@end
我们需要为占位符视图控制器设置这些属性和自定义类。还将链接视图控制器与ExternStoryboardSegue。