2

I have read in multiple places that only one UIViewController should be on screen at a time. But I don't quite understand how to accomplish what I need otherwise.

Imagine the weather app. There is a single view controller with a scroll view, to which multiple views are added (the weather panels). Presumably these are all added and managed by the main UIViewController, which is also responsible for scrolling, etc.

But imagine each of those weather panels was instead a CarView, each with data about a specific type of car, and some controls to edit that data.

Wouldn't it make sense to have a series of CarViewControllers, each with a Car property that they can manipulate? Each CarViewController would be responsible for it's car data object, it's view, and glueing them together, and the main view controller would simply be responsible for adding each carViewController.view to its scrollview.

Isn't this better for re-usability and encapsulation? Not to mention more convenient.

Ben Packard
  • 26,102
  • 25
  • 102
  • 183

2 Answers2

1

I think it just comes down to whether it will make your life easier or not. One alternative I like to do is to just write composite UIView subclasses specifically for displaying a "conceptual" model - like a car - and then write categories on them to populate the view information using a specific model implementation. That way you can re-use the view when changing your model but still keep some of the logic from cluttering up the view controller. I try to reserve a view controller for something like radically different views toggled with a UISegmentedControl or something.

Edit: an example of a UIView and its populating category.

@interface CarView : UIView

@property (strong) UILabel *modelLabel;
@property (strong) UILabel *makeLabel;
@property (strong) UILabel *yearLabel;
//etc

@end

Then you have a model-specific category, that while a category on the view really fits more into the controller layer; while a little bit of a breach of MVC I think it works nicely from a responsibility assignment standpoint, doesn't couple your main view implementation to any data implementation, and keeps your view controllers leaner, so I think it's worth the tradeoff.

@interface CarView (CarEntityPopulating)

- (void)populateFieldsWithEntity:(NSManagedObject *)entity;

@end

@implementation CarView (CarEntityPopulating)

- (void)populateFieldsWithEntity:(NSManagedObject *)entity
{
    self.modelLabel.text = [entity valueForKey:@"name"];
    self.makeLabel.text = [[entity valueForKey:@"make"] valueForKey:@"name"];
    self.yearLabel.text = [[entity valueForKey:@"year"] stringValue];
    //etc....
}
Carl Veazey
  • 18,392
  • 8
  • 66
  • 81
  • You mean something like [carView populateViewInfoWithCar:(Car *)car]? Where carView is a UIView instead of a UIViewController? – Ben Packard Oct 01 '12 at 21:33
  • Yes, except I would never do something like call a non-property method with dot syntax ;) But yes... I'll add an example I had in mind. – Carl Veazey Oct 01 '12 at 21:34
  • (oops - corrected!) How would you handle multiple controls on that view that are supposed to update the properties of the car? Lots of delegation to the main ViewController? – Ben Packard Oct 01 '12 at 21:36
  • 1
    That's a really good question actually. I would mainly use this for presentation of data. I also this a lot for table cells, so I do delegate back to the table's delegate in those cases. Or maybe the cell will have one button; I'll either delegate to the table controller or pass a block to the cell - shakes down the same responsibility-wise. And while there's nothing stopping you from implementing actions in the category, and setting the view itself as the target, that starts to seem too far over the line, and I'd think to try a different solution at that point. – Carl Veazey Oct 01 '12 at 21:46
  • Yeah - my current implementation is working ok with multiple carViewController.views added to the mainController.view (the CarViewController has a Car property and handles all of the display and updates). I just see a lot of references to it being a bad idea, and I'm encountering some side issues. Perhaps I will persevere instead of starting over. – Ben Packard Oct 01 '12 at 21:53
  • 1
    @BenPackard sounds like you are managing an interaction between the view and the model then which is a better fit for a view controller. If you post the side issues in other questions it would be interesting to evaluate them. You always write good questions which are fun challenges. – Carl Veazey Oct 01 '12 at 21:56
0

It seems like this now explicitly supported in iOS 5 using a container view controller.

There are not a lot of resources yet that discuss it, but this WWDC session is useful.

This question also provides some resources.

Community
  • 1
  • 1
Ben Packard
  • 26,102
  • 25
  • 102
  • 183