Cocoa touch view/view-controller conventions - cocoa-touch

I'm new to iOS dev and am working with an existing project. I just have a quick question regarding how views and view-controllers should be conceptualized and what the conventions are for dealing with them.
I noticed that the base UIViewController class has a property view which references an actual "physical" (for lack of a better word) view, while the controller essentially manages that physical view (and ties it to the model, etc--standard mvc stuff I understand).
This would suggest the view controller takes conceptual precedence in cocoa touch. However, when adding a subview (to a parent physical view? or to a parent view controller?) it accepts a physical view, not a view controller.
Is it expected that I first create the sub view controller (which presumably creates its own physical view) and then pass its view property to addSubView? I just want to make sure I'm not missing something obvious in the conventional workflow here.

Views and view controllers aren't in a 1:1 ratio. A view controller manages as many views as it needs to for a given area of functionality - on the iPhone, typically a screen full of content but this definition is shifting slightly.
The view property of a controller is simply the parent view - this can have as many subviews as you need to do the job. The controller coordinates between those views and the data model to deliver the functionality of your app.
You can have child view controllers, which are added to the view controller hierarchy as well as the view hierarchy (the child view controller's view is added as a subview of the parent view controller's view) but you wouldn't do this for every subview.
There was an excellent talk in WWDC 2012 ("The evolution of view controllers", IIRC) which explained this pretty well.

Related

Custom segue that 'finishes' early?

I'm looking to implement a custom segue that pushes to a UIViewController, but completes before the new UIViewController fully fills the screen, leaving some of the source view controller still in view and functional. (For example; new view controller covers half of the user interface).
I'm keen to use a segue rather than a view that is moved using CGRect, Quartz framework method, or similar, as constraints get messy really easily, unless a custom segue could utilise such methods(?)
Any pointers greatly welcomed! :)
For this task you would use a container view controller, which manages and displays the content of multiple other view controllers at a time while letting them interact with their views like normal. An example of this would be the UISplitViewController, which displays two view controllers' views at a time, one on each side of the screen. You can design segues that swap out one view controller of the multiple on display in a container view controller, similarly to the Replace Segue implemented by Apple to swap out a UISplitViewController's detail view controller (the one on the right hand side).

Rotate View which is insider another View

Today, when implementing my program i get a problem.
I have three types of views (small view). From them i make another view. (Templates)
When full view I add to viewcontroller.
As i think, willAnimateToRotation... For small views will not work correctly, because they are inside template. And template inside ViewController.
When app rotates i need to change frames for small views.
What should i do? How to perform frame change in rotation?
Views are adding to template with addSubview and template to VC also. I pass data to small view from template.
I'd translate this as a ViewController containment problem. You need to forward the rotation messages throughout your view hierarchy, otherwise it'll never reach your small views.
Best thing to do is to look at the documentation here:
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html
Go to the "Implementing a Container View Controller" sub-heading for a description and the "Managing Child View Controllers" sub-heading for relevant code.

Why need to add subview again after add child view controller?

Since I hava a parent view controller and a child one,
parent view controller is something like a container controller that apple doc said,
then do
[parentVC addChildViewController:childVC];
childVC.view.frame = SOMEFRAME;
but now childVC has not been seen in the screen;
must I add code below?
[parentVC.view addSubview:childVC.view];//is a must? any code can replace?
--
At my sight,container is container,when I had added a childVC in,it's view should add itself,or some method can do that?.
UIWindow has a property of "rootViewController",when set it,the new view will be added automatically,I think this is what I want.
I need some advices.thanks.
It's a simple matter of control. Often you want to have a child view controller, but it's view is a subview of one of your subviews, not simply a subview of the "top level" view property of the container view controller.
Essentially, the framework chooses to let you decide, and does not enforce that a contained view controller's view must be a first-generation decedent of it's parent view controller. It's completely up to you; the hierarchy of ViewControllers and Views do not need to have perfect generational parity.

A view switching framework for "true" MVC on iOS

I don't like the UINavigationController because the tree/drill-down navigation style does not work in all situations. What I'm looking for is a sort of UISwitchController where a view controller can tell the UISwitchController what the next view is and the data to pass to it. Then the current view closes itself and the UISwitchController would handle opening the next view and passing in the data from the previous view. The UISwitchController could remember the name/type of the last view opened so the current view could tell who opened it (also allows the UISwitchController to handle a Back request by the current view without the current view specifying the name of the view that opened it). A view could also flag the UISwitchController to keep it in memory and not to release it after it closes so the view controller is essential reused for each call to that view. Is there such an framework?
So basically you are talking of a UIViewController that holds several UIView(Controller)s and handles the presentation.
In iOS < 5 I would just use a UIViewController, that adds views to another view, that is displayed.
in iOS 5+ you should familiarize yourself with UIViewController Containment, that is actually a pattern of how to use UIViewControllers with other child view controllers.
form the UIViewController doc
Implementing a Container View Controller
In iOS 5.0 and later, custom UIViewController subclasses can also act
as container view controllers. A container view controller manages the
presentation of content of other view controllers it owns, also known
as its child view controllers. A child’s view can be presented as-is
or in conjunction with views owned by the container view controller.
Your container view controller subclass should declare a public
interface to associate its children. The nature of these methods is up
to you and depends on the semantics of the container you are creating.
You need to decide how many children can be displayed by your view
controller at once, when those children are displayed, and where they
appear in your view controller’s view hierarchy. Your view controller
class defines what relationships, if any, are shared by the children.
By establishing a clean public interface for your container, you
ensure that children use its capabilities logically, without accessing
too many private details about how your container implements the
behavior.
Session 102 - Implementing UIViewController Containment — WWDC 2011
I haven't used it much so I don't know if it's exactly what you're looking for, but you can use TTNavigator from the three20 framework to do URL based navigation which sounds like it could be what you want.
https://github.com/facebook/three20

Is it wise to "nest" UIViewControllers inside other UIViewControllers like you would UIViews?

I've got a fairly complex view, for me anyway, that has a few "trays" with custom interface items on them. They slide in and out of my root view. I'd like to nest (addSubview) the items inside the view. Each needs some setup before being displayed...and none can be configured in IB (they're subclasses of UIView).
I'm wondering if it makes sense to subclass UIViewController for each "tray" and then have the VC's view property point to the "tray" view which I can populate with my custom UIView objects. This way I can leverage the viewDidLoad, etc... methods in UIViewController.
I'm not aware of others doing this - at least in the few samples I've looked at. It would create a situation where there would be multiple view controllers being displayed on the screen at once. from the Navigation controller itself on down to the rootViewController and its view and then any number (well, screen size permitting) of these small trayViewControllers. If so, how's the responder chain work? i assume it'd go from lowest UIView to its enclosing VC, then to that VC's parent view, then that view's VC, etc. etc. repeat, repeat.. up to UIApplication... am I asking for trouble?
OR, do I just stick with UIViews and adding subviews into subviews, etc. etc..
Prior to iOS 5.0 this will specifically not recommended because the nested view controllers' lifecycle events – viewWillAppear, etc. – won't be called. See Abusing UIViewControllers.
With multiple UIViewController’s views visible at once some of those controllers may not receive important messages like -viewWillAppear: or -didReceiveMemoryWarning. Additionally some of their properties like parentViewController and interfaceOrientation may not be set or updated as expected.
iOS 5.0 added containment UIViewControllers that correctly handles those lifecycle events by adding child view controllers.
- (void)addChildViewController:(UIViewController *)childController
I spent countless hours trying to get nested view controllers to work in iOS 4. I eventually did, but it required a lot of glue code that was easy to get wrong. Then I saw the warning in the docs.
I'm trying to do the same thing, but was dissuaded from your approach by Apple's documentation, which states that "You should not use view controllers to manage views that fill only a part of their window—that is, only part of the area defined by the application content rectangle. If you want to have an interface composed of several smaller views, embed them all in a single root view and manage that view with your view controller."
My experience on what you are trying to do has been a good one. I try to keep nib files as simple as possible, so I take any posible "subview" and encapsulate it in its own nib file with it's own view controller, therefore I end up having nested view controllers.
In one of my apps I have a very complex table view cell, that has a subview. So I ended up having a hierarchy that goes like this: the tableview controller on the top level, the tableviewcell's controllers for each row and inside each of these a subviewcontroller for the subview inside each cell.
And everything works fine.
Pardon my english.