views:

1179

answers:

8

I have always sort of wondered when to use a UIView vs. a UIViewController on the iPhone.

I understand that you shouldn't use a UIViewController unless it's a full-screen view, but what other guidelines are there?

For example, I want to build a modal overlay - a screen that will slide into place over the current screen. If this modal overlay is full-screen, should it be a UIViewController? The last time I built something like this, I subclassed UIViewController, but now I wonder if that was correct.

A: 

Is the thing that slides in a self contained screen? I mean, does it directly interact with the parent? If so, make it a UIView, if not, probably recommend a UIViewController.

marcc
In this case, the overlay is part of a Lite application. When the user tries to do a restricted activity, then the modal overlay pops up and warns them. It will be used across several view controllers, but it will say different messages depending on the action the user tried to take. The overlay basically has a message and a small UIWebView to show a clickable ad that takes them to the full version on the app store.
Andrew Johnson
Interesting. I think this could go either way, but I'd probably make this as a UIView. I think UIView is easier to reuse on other UIViewControllers. But it is certainly opinion.
marcc
I did that in my app: user hit level 3 and I put up a view that said "You have reached the last level. Please click here to go to the app store and purchase the full version." It got rejected by Apple.
mahboudz
Ah. But with in-app purchasing allowed in free apps now, change that View to "click here to buy the rest of the levels" and you have a solution.
marcc
+2  A: 

This is a great question.

My basic rule of thumb. Is that every major 'page' of an application gets it's own view controller. What I mean by that is that during the wire framing stage of application design, everything that exists as its own entity will eventually be managed by its own View Controller. If there is a modal screen that slides over an existing screen, I will consider that to be a separate 'page' and give it its own view controller. If there is a view that overlays and existing page (such as a loading screen or help popup.) I would treat those differently, implement them as UIView subclasses and keep the logic in that 'pages' view controller. It the popup has behavior I will communicate back to that pages View Controller using the delegate pattern.

I hope this helps. It is very much a philosophical and architectural question and much could be written about it.

Brad Smith
A: 

I use UIViewController whenever a view is full screen and either has outlets/actions and/or subviews.

Art Gillespie
A: 

A UIView is part of the UIViewController see the view property of UIViewController for this. As you pointed out correctly UIViewController manages a complete screen and there should be only one visible UIViewController at a time. But in most cases you will have more UIViews or subclasses of UIView visible on the screen.

The example you gave would be a correct use in most cases. As you may have noticed you will get a lot of functionality when subclassing the UIViewController. Animating the appearance and dismissal of the UIViewController would be one of them.

As marcc pointed out if the thing you want to slide in is not a self contained screen you would be better off using a UIView.

As a conclusion I would say that if you want to use the functionality that comes with subclassing UIViewController than go for it make it a UIViewController. Otherwise a UIView might be better.

The itunes U Standford class has a great lecture on UIViewControllers I would recommend watching it, because it has a lot of information regarding UIViewControllers in general.

sliver
A: 

Put everything on a screen into a UIViewController until the view controller starts to have too much code, then break out the screen into multiple UIViewControllers contained by one master view controller...

Kendall Helmstetter Gelner
+5  A: 

I highly recommend reading Apple's UIViewController Programming Guide (http://bit.ly/2L3eT2).

The main practical reason to use a custom UIViewController, especially in a simple application that doesn't use navigation, is to handle rotation. UIWindow and UIViewController work together to determine whether or not the top-most view can handle rotation, and which orientations it supports.

If you just used a view, without having that view managed by a UIViewController subclass, then the application window wouldn't consider that view a candidate for rotation. UIViewController is the magic ingredient that makes auto-rotate possible.

Remember that all UI controls and even the main window itself are all "views", ie they are subclasses of UIView. So you're using views all the time. The idea behind a view is mostly that it takes responsibility for drawing a portion of the screen, so obviously the screen can contain many different views at the same time, and views can contain other views (in the same way the main window does, being a view itself).

The reason Apple recommends to have a UIViewController manage a whole screenful of space is because of the rotation system. Only one UIVC -- the one attached to the most recently, top-most added subview of window, or a current modal pop-up view -- will ever be asked to verify if orientation changes are possible. And ONLY the view associated with that one UIVC will actually be rotated. That's an important point to remember... If you have two UIVC objects managing the current screen contents then only the newer view could change orientation, potentially leaving the display in a mess.

So, in a nutshell, if you have a simple window-based app and don't need to worry about rotation, it's fine to just use your regular controls placed directly on the main window and ignore UIViewController altogether. You'll still need to provide a generic "controller" to handle layout changes and behavior, and to mediate data changes between the controls and your model(s), but that controller doesn't need to inherit from UIViewController, it can be a subclass of NSObject.

DX Griffiths
A: 

I have a somewhat different approach:

Override UIView if you plan to do custom drawing in drawRect. Otherwise, subclass UIViewController and use [self.view addSubview: blah] to add the components of the page.

There are a few other special cases, but that handles about 95% of the situations.

(You still will often need a UIViewController with a custom UIView. But it's common to have a custom UIViewController with no corresponding custom UIView.)

Amagrammer