Pos*_*ism 3 iphone storyboard uiviewcontroller ios
我在我的故事板中设置了这个UIViewController,包含了我需要的所有插座,视图和约束.完善.让我们调用这个WatchStateController,它将作为一个抽象的父类.
然后我有了WatchStateController的这个子类,叫做WatchStateTimeController,它将具有我需要的特定应用程序状态的功能.
因为我试图在UIStoryboard中使用1视图控制器,我在将WatchStateTimeController实例化为类型WatchStateTimeController时遇到了一些问题 - 它实例化为WatchStateController.
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
WatchStateTimeController *timeController = (WatchStateTimeController *)[mainStoryboard instantiateViewControllerWithIdentifier:@"WatchStateController"];
Run Code Online (Sandbox Code Playgroud)
这是因为故事板的Identity Inspector中的"Class"字段设置为"WatchStateController".所以问题是,我如何仅在运行时更改Identity Inspector中设置的类名?

注意:忽略我为什么要这样做并专注于如何做到这一点.如果你真的必须知道原因,你可以阅读战略设计模式.
小智 6
我用来强制故事板与策略模式兼容的一个稍微脏的解决方法:我在基础(抽象)视图控制器中编写一个自定义分配器,它在故事板机制结束之前返回所需的具体视图控制器子类的实例.
为此,您必须告诉基类要实例化的子类.
所以,在基本控制器中:
Class _concreteSubclass = nil;
+ (void) setConcreteSubclassToInstantiate:(Class)c {
_concreteSubclass = c;
}
+ (id)allocWithZone: (NSZone *)zone {
Class c = _concreteSubclass ?: [self class];
void *object = calloc(class_getInstanceSize(c), 1);
*(Class *)object = c;
return (id)CFBridgingRelease(object);
}
Run Code Online (Sandbox Code Playgroud)
这也为子类的ivars实例化了足够的内存.
故事板中已知的视图控制器类型"MyViewController"只是"BaseViewController"; 但是,在你要求故事板实例化视图控制器的地方,你可以这样做:
[BaseViewController setConcreteSubclassToInstantiate:[SomeSubclassOfBaseViewController class]];
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil];
SomeSubclassOfBaseViewController *vc = (SomeSubclassOfBaseViewController *)[mainStoryboard instantiateViewControllerWithIdentifier:@"MyViewController"];
[self presentViewController:vc animated:NO completion:^{}];
Run Code Online (Sandbox Code Playgroud)
具体的视图控制器被实例化并显示没有故障.
以下是使用辅助对象的策略模式示例,如我在评论中所述:
@class WatchStateController;
@protocol WatchStateStrategy <NSObject>
- (void)doSomeBehaviorPolymorphically:(WatchStateController *)controller;
@end
@interface WatchStateController
// or call this a delegate or whatever makes sense.
@property (nonatomic) id <WatchStateStrategy> strategy;
@end
@implementation WatchStateController
- (void)someAction:(id)sender
{
[self.strategy doSomeBehaviorPolymorphically:self];
}
@end
@interface WatchStateTimeStrategy <WatchStateStrategy>
@end
@implementation WatchStateTimeStrategy
- (void)doSomeBehaviorPolymorphically:(WatchStateController *)controller
{
// here's one variation of the behavior
}
@end
@interface WatchStateAnotherStrategy <WatchStateStrategy>
@end
@implementation WatchStateAnotherStrategy
- (void)doSomeBehaviorPolymorphically:(WatchStateController *)controller
{
// here's another variation of the behavior
}
@end
Run Code Online (Sandbox Code Playgroud)
要在呈现视图控制器时进行设置,请分配适当的帮助程序对象(而不是尝试更改视图控制器本身的子类):
WatchStateController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"WatchStateController"];
if (useTimeStrategy) {
viewController.strategy = [WatchStateTimeStrategy new];
} else {
viewController.strategy = [WatchStateAnotherStrategy new];
}
Run Code Online (Sandbox Code Playgroud)
与子类化视图控制器相比,我看到这种方法的优点:
| 归档时间: |
|
| 查看次数: |
2306 次 |
| 最近记录: |