Make a view whose contents appear across all storyboard scenes - objective-c

My app is made of 2 storyboard cenes, but these have a mutual UILabel whose value shouldn't change with the change of the scene, (as it does now) so I was thinking of moving this label to a view that would be on both controllers, how can this be done?

You would simply have an outer ViewController with the label in it's view. Two more view controllers have the scenes, and their views are subviews of the outer view controller.
Perhaps the inner view controllers use a navigation controller, or whatever is appropriate for your needs.

Related

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.

ios - splitviewcontroller inside tabbarcontroller using storyboards

I have my app mapped out using storyboards where there is an entry screen that segues to a tabbarcontroller which contains 3 tabs. Each tab contains a splitviewcontroller and I have written classes for each master and detail view controller. The bit I'm not sure on is how to give each masterviewcontroller (that controls the table on the left hand side) a reference to the detailviewcontroller.
I can see in the attributes inspector there is an identifier field, should i put something in here for the detailviewcontroller (e.g. 'detailviewcontroller1) and then somehow get that object by it's instance name in code?
Both your master and detail view controllers will have a property, splitViewController, that holds a pointer to the split view controller.
The split view controller has a property, viewControllers, which holds an array of the view controllers contained in the split view. This array will always contain 2, and only 2, view controllers - at index 0 is the master controller, and at index 1 is the detail controller.
So your SplitViewController should be connected to 2 segues that connect two separate UINavigationControllers (one for Master and one for Detail). These two nav controllers will connect to your two VC's (Master and Detail).
You will then create a property for that detail VC inside the master VC and pass whatever data you need to when the user selects a row from the TV.
If you need to see how this is supposed to be layed out and wired up, just create a new iPad application using the Master-Detail template.

How do you hook up IBOutlets across scenes in the Interface Builder storyboard?

I have a custom UITableViewController with 2 properties:
#property (strong, nonatomic) IBOutlet VenueHeaderViewController *header;
#property (strong, nonatomic) IBOutlet VenueFooterViewController *footer;
The UIViews of my VenueHeaderViewController and VenueFooterViewController were designed in IB. Each of these controllers has IBOutlets to its subviews as set up in the storyboard. This is my storyboard:
My question is, how do I now connect my header and footer IBOutlets inside my UITableViewController to instances of my VenueHeaderViewController and VenueFooterViewController while retaining the layout and IBOutlets which I have set up in the storyboard?
You can't hook up IBOutlets across different scenes in a storyboard. Scenes are each entirely self-contained, and only connected via segues (or relationships in the case of special container view controllers like tab, navigation, split view and popover controllers). If you've done any IB work without storyboards, think of each scene (view controller) as being in its own nib (in fact, that's what storyboards do behind the scenes).
Beyond that, it's generally the case (on iPhone at least) that there's a one-to-one mapping between a view controller and a "screen" of UI -- you generally don't have different view controllers managing different parts of the screen, as appears to be the case with the header, table, and footer you have. (Thus, you'll pretty much never have an IBOutlet to any UIViewController subclass.)
So what can you do? Here's a few different approaches, from easier to harder:
UITableView header & footer
If you're meaning to assign those header & footer views to the UITableView's tableHeaderView and tableFooterView properties, you can do that in the storyboard in IB -- just drag a UIView of some sort from the library toward the top or the bottom of the table until you see a blue line above or below the prototype cell(s):
The table header & footer views might or might not be what you're after, though: they're part of the scrolling content of the table (that is, they appear above the first row and below the last, respectively, so they can be scrolled off the screen).
Views above & below
If your intended use of these views is as "header" and "footer" in that they always appear above or below the table regardless of where it's scrolled, then what you really need is to have the header, footer and the table view all be subviews of a root view.
For that, you'll need a regular UIViewController subclass rather than a UITableViewController subclass. You can put a UITableView in as a subview of that view controller's root view, and arrange whatever other views you want to be visible above/below it. (Just make sure to set the autoresizing sensibly if you plan to support rotation.) Here's an example:
(If you're wondering where the prototype cells are when you first drag out the table view, check the inspector -- you set the number of them in the upper right of that screenshot.)
Top level views
With regular nibs (not storyboards), you can set up views in IB which aren't the view controller's root view. Then you can still connect outlets to them, and programmatically insert them into the view hierarchy as needed.
You can sort of do this in a storyboard, too -- drag views to the black bar beneath the scene -- but due to a bug in the current version of Xcode, you can't see these views for editing. Oops.
Multiple view controllers, really
If none of the above suit your needs, you might still have a use for multiple view controllers -- say, if you wanted to switch out different different header views at various times, and save memory by dynamically instantiating these view hierarchies as needed. Cases like this are pretty rare, though... you should make sure you've exhausted other options first.
In effect, you're still using one of the previous two approaches, but the views you want are located in other scenes (again, it's like they're in other nibs). Here, the view controllers holding the other views don't even need to be custom subclasses of UIViewController, since they're just temporary containers for views you want to insert into a different view controller's view hierarchy.
In that case, the storyboard you have is what you want... it's just a matter of getting those view controllers appropriately loaded, which you can do thusly:
SpecialViewController *svc = [storyboard instantiateViewControllerWithIdentifier:#"SpecialViewController"];
Then, pull the view property from each view controller, insert it into your "main" view controller's view hierarchy, and dispose of the the view controller you pulled it from.

Programmatically change subviews from within subview's controller

In my iPhone application I've set up a default, blank view called Main View into which various child subviews will be loaded for different parts of the application. It's the same approach as if I was using a tool bar to switch between subviews. That case, in the MainView controller I could hook IBActions to buttons in the toolbar, so that when a button was pressed, MainView added different subviews to itself.
In my situation, though, I need to tell MainView to change its subview from within the subviews. So here are two sister subviews, each with their own controller and xib, that would be loaded as subviews of MainView:
- StartView
- FormView
In StartView, after some animations and welcome stuff, a button triggers the camera image picker. Once the image picker returns the image, I need to tell MainView to remove StartView and add FormView.
It may be the result of a long day or my newness to iPhone OS but I'm stuck getting my head around the right way to set up my objects/controllers.
You never have more than one view controller active at a time. (The nav and tabbar controllers don't control views, they control other controllers.) In this case, you will have a single controller that has the MainView as its view property. It will add StartView and formView as subviews of MainView.
However, this is not a good design. It will overload the MainView controller by forcing it to juggle many views. It would be better to use a hidden navigation controller or a tabbar. Hierarchies of controllers can create the illusion from the users point of view for almost any interface layout you can imagine. There is no need to create a logical structure that mimics the visual one.
From your description you may only need a single view/view-controller pair: Set the formView controller to open the camera view before it displays the formView. When the camera is dismissed it reverts to the formView automatically. No fuss, no muss.

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.