Issues that can arise when using UIViews instead of UIViewControllers? - objective-c

I've been trying to figure out what can go wrong when using UIViews instead of UIViewControllers and haven't been able to find any therefore I've been just using custom UIViews when generally UIViewController is recommended for some reason.
I prefer UIViews mainly because when custom animating for transitions they're easier to manipulate as far as I know. Correct me if I'm wrong.
Also, I customize everything on my own programmatically such as tab bar, navigation bar etc hence to me, a custom UIView does everything a UIViewController does..
So, is using a separate custom UIView instead of a new UIViewController problematic? If so, please enlighten me..!
Edit
I am aware of MVC model and by UIViews instead of UIViewControllers I mean ignoring the whole one UIViewController per screen thing and use UIView as a container for all objects for certain screens.
For example, when showing menu screen, instead of pulling a UIViewController up for its own "section", I just don't do UIViewController at all and do it with a custom UIView which works as a container, draw/add everything in there. The same goes for the rest of "sections".(settings, option etc etc)
Is this problematic?

I've been trying to figure out what can go wrong when using UIViews instead of UIViewControllers
You cannot do it generally, because view objects and view controller objects occupy different places in the Model-View-Controller hierarchy. They are not even one-to-one with each other, because a single controller often manages multiple views.
I prefer UIViews mainly because when custom animating for transitions they're easier to manipulate as far as I know.
In situations when a piece of functionality can reasonably go in either a view or in a view controller, it most likely belongs in the view, not in the view controller, so your observation is correct. Custom animation that can be encapsulated in a single UIView should be encapsulated in the UIView, even though the same code could go in a UIViewController as well.

Related

multiple view controllers strategy

I am making an app that has about 20 different view controllers that are loaded into a single container view. Some of the views have sliders and buttons and some have only buttons.
Is there a strategy I can use to make building the views controllers more inline with Objective C coding techniques?
Currently I am trying to combine similar methods into model objects but before I get too involved I thought I'd ask if there is a better way. I'm also willing to do the groundwork and research so any keywords to point me in the right direction would help, i.e. protocols, delegates, etc.
The main piece of advice I'd give you is to consider whether or not each one of those view objects needs to be controlled at all. Consider UIViewController like the delegate between the view and the model. If you don't need an extreme context switch (i.e. pushing a new view onto the navigation stack), then is it really advisable to have 20 delegates floating around? In most cases, not really. UIViewController is not a "heavy object" by any stretch of the imagination, but it can quickly make your codebase unwieldy and large if every time you decide to throw a new component onto the screen, you subclass UIViewController.
Try to focus your attention on dividing the logic to setup the view and the actual responsibilities of the controller (reacting to model changes, dispatching operations, updating the view) into a UIView subclass and a UIViewController subclass respectively. If you truly do need to keep some component of the view separate because its logic simply cannot fit under the main view controller's category of responsibilities, then, and only then, is a new view controller appropriate.

Subview vs childViewController

This is a general question but I'll ask it using a specific example to avoid confusion:
I'm developing an app that has a UIPickerView among other things on a single screen. I was wondering if it's appropriate the make a custom PickerViewController class to control my UIPickerView and then add my PickerViewController as a childVC...
OR should I just create an instance of UIPickerView in my existing VC and control it from there?
When should I do either of these options and what are the advantages of them?
Appreciate the help amigos.
If the UIPickerView is simoultaneously on the screen along with other UI elements, then you should just add it as a subview. The concept of a view controller is for when you start managing a completely different UI/window/set of elements (however you call it). If the picker view closely belongs to the functionality of the other elements, you should not create a separate view controller for it.
iOS 5.0 introduced the notion of child view controllers. Originally, any view controller except for UINavigationController and UITabBarController had to be modal and full screen. In iOS 5.0, you can now have several UIViewControllers present on one screen. This means that one UIViewController can have many children (UIViewController), where each child is responsible for controlling more specific views and models.

proper ios5 storyboard flow for a constant background / transparent views?

I have one background I want constant to all views; it shouldn't animate out and back to itself. I have another background I want common to another handful of views that layers on top of that one. I could do this cleanly enough by:
a) just having one viewcontroller and managing all the transitions of layered objects within that
b) using separate viewcontollers and managing them programatically
But I don't grok how I can do this with a storyboard proper-like. Do I need to make a custom segue? Is there a certain type of segue it should be, if it's custom (or otherwise)? Is there a best viewcontroller that I do it all inside? (note: there's no "levels" of navigation, tab bar, navbar, etc... though if that's the way to go, with the elements hidden, and that's the "best" way to do it, I suppose that that might be me c)? )
Hope I've explained this well enough. :) I do grok layer transparency, etc, as far as views go....
Thanks!
ETA: After more research, I thought I understood c as the correct answer, (with a nod to set "default" UIViewController background image? ) ~
navigation controller with main background
navigation controller with secondary background elements
subpage 1
subpage 2
subpage 3
other controller
But I'm still hitting a wall. Not grokking the storyboard (IB) way to even add a background to a navigation controller. The number of custom classes I've made and tossed out, now....
See if this is what you need. It is not in storyboard, but should do well enough.
navViewController.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"background.jpg"]];
This is what I have done (but only with 1 level of nav controller). You can put this code in AppDelegate.m, or maybe subclass UINavigationViewController and change the view's backgroundColor there (and attach it within StoryBoard)
I guess the problem is StoryBoard still has some limitations. And UINavigationViewController is not an interface element, it is a View Controller. It is simply shown as a simulated element in StoryBoard.)

Putting an ADBannerView on top of a UINavigationController

I'm trying to put an iAd banner in an app that is based on a UINavigationController (it's not the standard nav-base app proposed by xcode, cause I don't need the table view).
I'd like to place an ADBanner on its bottom, to be always visible, no matter how the user pops and pushes views.
I studied the iAdSuite example in the apple sample code, but, though it's reported among the "best practices", I don't think it's the best practice for what I need. It basically declares an ADBannerView in the app delegate class and then implements the ADBannerViewDelegate methods for every single view the app needs. That means implementing the ADBannerViewDelegate methods over and over again on every view controller class you need! It doesn't seem too smart... :(
I'd rather prefer to have an approach more similar to what Apple itself does in the tab bar based app, where you have a part of the window always occupied by the tab controller and all the views switching above without affecting the tab bar view below.
You can't directly put an ADBannerView along with the nav controller in the app delegate, because ADBanner needs to be placed in a view controller (you get a runtime error otherwise).
I tried to subclass from UIViewController, implementing the ADBannerViewDelegate in this class, and place it in the rootViewController along with a UINavigationController but I'm not having good luck with this approach...
Has anybody found a good, simple way to to this? Any hint?
Thank you for any help...
You can have just one class for ADBannerViewDelegate, and just one instance of ADBanner itself. When the currently active view changes, remove ADBanner from the old view, add it as a subview to the new view.
EDIT:
to clarify, you don't need each view implement the ADBannerViewDelegate. You only should have one class implement it (that class doesn't have to be a view controller for that matter).
You would also need to maintain a somewhere a property that would point to the currently active view (e.g. you can update that property in your Navigation Controller's navigationController:didShowViewController:animated:, or come up with your own protocol for that if your views appear in a more complex way).
Then in your ADBannerViewDelegate you'd just resize the view currently pointed to by that current view property. The actual view doesn't even have to know it has an ad in it ;)

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.