我有一个父类DocViewController(继承自UIViewController)和2个子类:
在父类(DocViewController)中,我有以下代码:
if ([previousView isKindOfClass:[PhotoViewController class]] || [previousView isKindOfClass:[MapViewController class]]) {
[viewControllers removeObjectAtIndex:[viewControllers count] - 2];
self.navigationController.viewControllers = viewControllers;
[viewControllers release];
}
我正在使用从UINavigationView堆栈中删除子类。 (这不是关于这个问题:我有一个分段控件,我正在推动这些类,但我仍然希望我的“后退”按钮忽略它们。)
有效。我唯一的问题是不是非常面向对象,因为父类导入了if语句的子类。对吗?
感谢
答案 0 :(得分:2)
是的,它不是面向对象的。最好在类上实现一个方法。也许像是
-(BOOL)shouldPopTwo;
然后
if ([previousView shouldPopTwo]) { ... }
然后每个子类都可以根据需要实现。
<强> BUT 强>
在大多数情况下,我认为你应该避免使用UIViewControllers构建类层次结构的诱惑。控制器通常是MVC设置中可重用性最低的对象,因为它们旨在非常具体地定义行为并将其映射到特定的Model对象。当然可以构建层次结构(正如它们在SDK中一样),但结构,功能和抽象需要非常仔细地规划和构建。
相反,您应该创建可重用的UIViews,然后实现不同的UIViewControllers来定义应用程序应该如何使用和响应这些视图。
回应以下评论:
听起来您可能正试图以不适合的方式使用导航控制器,实际上您的最后两个视图控制器应该是单个视图控制器。视图控制器主要用于管理全屏幕内容。如果我理解正确,在你的情况下你有一个分段控件应该留在屏幕上并负责在剩余的可用空间中切换内容。我建议你有一个视图控制器,它的视图将包含分段控件和一个'画布',用于显示备用视图。视图控制器将保持对它正在管理的视图的引用,以便它可以切换它们(如果你想要UINavigationController风格的动画,你必须自己实现)。
最后,您需要决定:此单个视图控制器是否可以充当两个子视图的控制器?或者每个视图都有自己的控制器?如果这个UIViewController子类是一次性的,它只适用于这两个视图(比如PhotoMapViewController),你可以选择第一个更简单的选项。如果你想让它与任何UIView(比如SegmentedControlViewController)一起使用,那么每个视图都应该有自己的NSObject控制器(而不是UIViewController)。来自apple docs:
注意:如果要分割视图 层次结构分为多个子区域和 分别管理每一个,使用 通用控制器对象(自定义 来自NSObject的对象) 而不是视图控制器对象 管理每个分区。然后用一个 查看控制器对象来管理 通用控制器对象。
但这需要更多的抽象和设置。
如果总体目标是(我猜)映射一组照片,在调用视图控制器的第一种情况下,您可能会有以下代码:
NSArray *photoCollection = model.myPhotos;
PhotoMapViewController *pmViewController = [[[PhotoMapViewController alloc] initWithPhotoCollection:photoCollection] autorelease];
[self.navigationController pushViewController:pmViewController];
和PhotoMapViewController:UIViewController将负责创建和初始化其分段控件管理的两个视图。
我不会进入第二种情况的代码,因为它更精细。
最后,看看OOP原则,即支持组合而不是继承,以便更广泛地了解为什么你可以采用这种方式而不是第一次实现。
每当你开始设置一个类层次结构时,你应该问自己 - 它真的是一个子类吗?然后停下来问自己 - 没等等,它真的是一个子类吗?祝你好运!