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.)
Related
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.
So I'm curious. I was looking into a way to create a categories selector similar to the one located at the top of this application: http://itunes.apple.com/us/app/xfeed-rss-reader/id313206921?mt=8 ... 06921?mt=8. Would I tackle this using a Toolbar and elongating it to where the user can 'scroll' side to side for categories? Or a ScrollView with a Tabbar in it? I want to do this the 'proper' way per say and I've seen flags raised about a Tabbar being in a ScrollView.
If I were implementing this, I would create it with a UIScrollView containing UIButtons. UITabBars have some nice integration with UIViewControllers and UINavigationControllers, but the benefits quickly drop off when you need more customizable behavior (left to right scrolling, for instance.). I would normally just put them all in a xib and connect the outlets appropriately, unless it was important that they be dynamic.
You mentioned correctness, so an even more "correct" way is to create a UIControl similar to a UISegmentedControl that handles the creation of properly sized labels, deals with touches appropriately, etc. If you are setting categories dynamically you'll want to override sizeThatFits: and call sizeToFit so you can properly size the content area of your scrollview.
Lets say I have a scene which includes a UIView container on the top half of the screen, and a UIView container on the bottom half of the screen and a few buttons at the very bottom of the screen.
Basically the bottom container will always display static text while the buttons across the bottom will change the content of the top container which may include an image, more buttons, or more text depending on what button is pressed on the bottom. Also each time a bottom button is pressed the top container is transitioned to the new view with a flip from bottom transition.
I have achieved this purely programmatically, but decided to convert my app to a storyboard file since it makes producing the rest of my app much faster and simpler, plus makes the code not look like a crazy mess.
My limited understanding of storyboards seems to deduce that I would need a separate story board scene for every UIView change, and Apple's coding conventions with storyboards seem to imply that we should use a new ViewController every time you create a new scene. All this adds up to an even bigger mess than I currently have.
Is there a better way of doing this? Am I misunderstanding something? If I am not confused, is there some way to make all these scene and view controller duplication cleaner?
The storyboard editor makes it difficult to do what you're describing, because it doesn't let you edit freestanding views associated with a scene.
I suggest you just create a separate nib (not storyboard) for each of the top-half views. These can exist separate from your storyboard. Your view controller (which is instantiated from the storyboard) can then load whichever nib it needs when a button is pressed, and put the view from the nib into its (the view controller's) top-level view.
There must be a way!
I accidentally opened one one day (see attached image). Although I have no idea how I did it and really really want to know, I cannot reproduce it, nor close it. The UIView opened when I was dragging my connection for the table header view from the Connections Inspector to the list of controls on the left side of the screen (not to the actual UIViewController).
I too am reworking a project with storyboards and have a similar problem with multiple views per UIViewController.
In this case it is a table header. I have other UIViewControllers in the project with the same configuration but I cannot get them to pop up either.
I have a series of UIViewControllers throughout my application. Most of them have the navigation bar but some of them hide it.
The problem is that sometimes as you transition between a view with or without navbars to another view with or without navbars there is a black box that replaces the navbar during the transition. This problem was discussed here: Hiding a UINavigationController's UIToolbar during viewWillDisappear:
This solution is fine and it does get rid of the black box, but I really don't want what was described as a "Cheshire Cat" disappearance. I've tried myriad solutions using prepareForSegue, ViewWillAppear, viewWillDisappear, etc. The best I can do is change the scenario in which the black bar shows up.
By this I mean, there are four combinations of view transitions between the two navigation bar states (hidden vs. not-hidden):
Hidden - Hidden
Hidden - Not Hidden
Not Hidden - Hidden
Not Hidden - Not Hidden
No matter what solution I've tried, at least one of those combinations results in my black box rearing its ugly head. The problem I have is that I've been unable to find anywhere that I can get a reference to the source view controller and the destination view controller when popping a view off of the navigation controller's view stack.
If I could get both references in the same event, I could simply determine what the combination is and handle the behavior appropriately like I would in prepare for segue.
Now, I know that "it's not possible" is a reasonable (and even a probable) answer, but I won't accept that as a solution alone. If it is indeed not possible, I'd like thoughts on a reasonable alternative. For example, I could handle all view controller popping manually (including the default back button) and thus could get the "upcoming controller" from the navigation controller's stack.
I would just prefer a solution using built in APIs or at least a solution where my controllers didn't have to be aware of their own navigation bar states.
Thanks a lot,
Patrick
I think UINavigationControllerDelegate is what you're after. It declares two methods:
-navigationController:willShowViewController:animated:
-navigationController:didShowViewController:animated:
All you need to do is set yourself as the delegate of the parent navigation controller and implement these methods to be notified of incoming view controllers.
Having said that, I've never needed to resort to this for hiding and showing navigation bars. Strictly speaking, view controllers where the navigation bar will always be visible never touch the navigation bar's visibility. When I'm moving into a view controller where it needs to hide, that view controller is responsible for hiding and setting it back to its prior state before disappearing. Following these standards has proven reliable for me.
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.