开发者

iOS: better design with UIViewController parent-children classes

I have a parent class DocViewController (inheriting from UIViewController) and 2 subclasses:

  • PhotoViewController
  • MapViewController

In the parent class (DocViewController) I have the following code:

if ([previousView isKindOfClass:[PhotoViewController class]] || [previousView isKindOfClass:[MapViewController class]]) {

                [viewControllers removeObjectAtIndex:[viewControllers count] - 2];
                self.navigationController.viewControllers = viewCon开发者_JAVA技巧trollers;
                [viewControllers release];

}

That I'm using to delete the children classes from UINavigationView stack. (It is not about the question anyway: I have a segmented control and I'm pushing such classes, but I still want my "Back" button to ignore them).

It works. My only problem is that is not very object-oriented since the parent class import the children for the if statement. Right ?

thanks


Yes, it's not very object oriented. Would be better to implement a method on the classes. Maybe something like

-(BOOL)shouldPopTwo;

and then

if ([previousView shouldPopTwo]) { ... }

And then each subclass can implement as it needs to.

BUT

In most cases I think you should avoid the temptation to build class hierarchies with UIViewControllers. Controllers are typically the least reusable objects in an MVC setup as they are designed to very specifically define behavior and map it to specific Model objects. Certainly hierarchies can be built (As they have been in the SDK), but the structure, function and abstraction needs to be very carefully planned and constructed.

Instead, you should probably create reusable UIViews and then implement different UIViewControllers to define how the application should use and respond to those views.

In response to comments below:

Sounds like you might be trying to use a navigation controller in a way it wasn't intended for and actually your last two view controllers should be a single view controller. A view controller is primarily intended to manage a full screen's worth of content. If I understand correctly, in your case you have a segmented control that should stay on screen and be responsible for switching the content in the rest of the available space. I would suggest you have a single view controller and it's view would contain the segmented control and a 'canvas' which would be used to display alternate views. The view controller would hold references to the views it is managing so that it could switch them in and out (if you want UINavigationController-style animations you'll have to implement that yourself).

Finally, you would need to decide: Can this single view controller act as the controller for the two subviews? Or should each view have its own controller? If this UIViewController subclass is a one-off, and it is only intended for these two views (say PhotoMapViewController) you could choose the first, easier option. If you want this to work with any UIView (say SegmentedControlViewController), then each view should have its own NSObject controller (not UIViewController). From the apple docs:

Note: If you want to divide a view hierarchy into multiple subareas and manage each one separately, use generic controller objects (custom objects descending from NSObject) instead of view controller objects to manage each subarea. Then use a single view controller object to manage the generic controller objects.

http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/AboutViewControllers/AboutViewControllers.html

But that would require substantially more abstraction and setup.

If the overall goal is to (I'm guessing) map a collection of photos, in the first case in the calling view controller you might have code like:

NSArray *photoCollection = model.myPhotos;
PhotoMapViewController *pmViewController = [[[PhotoMapViewController alloc] initWithPhotoCollection:photoCollection] autorelease];
[self.navigationController pushViewController:pmViewController];

and PhotoMapViewController : UIViewController would be responsible for creating and initializing the two views its segmented control manages.

I won't go into the code of the second case because it's much more elaborate.

Finally, look to the OOP principle of favoring composition over inheritance to see a broader perspective of why you might do things this way instead of your first implementation.

Any time you start to set up a class hierarchy you should ask yourself - Is it really a subclass? and then stop and ask yourself - No wait, is it REALLY a subclass?? :) Good luck!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜