iPhone : UINavigation Controller within a view displaying another view - ipad

I think I am having a case of disappearing up my own arse.
I am creating a small view on a ipad thats for settings (so not full scree), within this view. I need a navigation controller to show another view.
At the moment I have one class / xib
The xib contains the main view (graphic / boarder). This view is linked to the files owner and appear.
On the same xib, I also have a navigation controller that contains the inner view.
OnViewDidLoad I add the navigationcontroller.view to the subview and it appears. However I cant push anything off it. I wired up the delegate and etc but I am sure I am missing something stupid
Can I do this all within one controller / xib?
The only code I have done is
[self.view addSubview:mainNavigationController.view];
Is there some code I need to do for the navigationController

Just adding the navigation controller as a subview doesn't hook up the navigation controller to the view controller hierarchy properly. That's probably why it doesn't work.
Also the properties that need to be set are readonly properties, so I don't think there's anything you can really do about it.

Related

IOS: One navigation view controller with many different views - how should I do it?

I'm trying to create an IOS app that has one navigation view controller with several bar buttons, where each button changes the content of the view itself. Most of my views are custom views anyway, so I won't really see any clear previews in the storyboard anyway.
I'm thinking about creating one navigation view controller, and several NIB files to represent each view. Each NIB will have its own class with all the IBOutlets and IBActions.
Then, when a button is clicked in the navigation view controller, just switch to a new view by clearing the old one (removeFromSuperview), and call loadNibNamed to load a new view.
Does this sound reasonable or will all this deserializing be expensive in terms of CPU? Would it be better to just create different viewcontrollers in the storyboard, with segues etc, and copy those nav bar buttons to each view controller?
The simplest solution:
ViewController->
View->
rootViewOne
rootViewTwo
rootViewThree
...
upon your bar button's action,set specific rootView's hidden property to true or false:
self.rootViewOne.hidden = currentIndex == 0
self.rootViewTwo.hidden = currentIndex == 1
self.rootViewThree.hidden = currentIndex == 2
You can add your other view controller/s as child view controller.
In this way, you will have code for different views in their respective view controllers and your main/parent view controller will not be messy.
To add child view controller:
// Get instance of your view controller
UIViewController *childViewController = [UIViewController new];
// Add your view controller as a child view controller
[self addChildViewController:self.loginView];
// Set frame for your childViewController's view
[childViewController.view setFrame:CGRectMake(0.0f, 0.0f, self.view.frame.size.width, self.view.frame.size.height)];
// Add childViewController's view as a subview to your viewcontroller's view
[self.view addSubview:childViewController.view];
// Notify your main/parent controller that a child view controller is being added
[childViewController didMoveToParentViewController:self];
To remove child view controller:
// Notify the childViewController that it will be removed
[childViewController willMoveToParentViewController:nil];
// Remove childViewController's view
[childViewController.view removeFromSuperview];
// Remove childViewController from your main/parent view controller
[childViewController removeFromParentViewController];
Hope this helps.
UPDATE - Embedded swapping by Sandmoose Software:
http://sandmoose.com/post/35714028270/storyboards-with-custom-container-view-controllers
Here's a snippet from the "how-it-works" section:
The segue between ViewController and ContainerViewController is an
embed segue. The segues between ContainerViewController and its two
child view controllers is a custom segue. This custom segue is named
Empty and is a subclass of UIStoryboardSegue. It contains an empty
perform method. The ContainerViewController will take care of moving
the child view controllers into and out of place. However, the fake
segues are needed to create the connections in the storyboard.
If you’re like me you cringe at the thought of having a fake/empty
class like this but the benefit is that it allows us to stay firmly in
the world of storyboard idioms without resorting to programmatically
loading isolated storyboard scenes. It’s one tiny bit of ugliness
which allows us to preserve the usefulness and elegance of
storyboards. The storyboard still visually represents the scenes and
their relationships accurately. We can still use segues to control
what happens.
---------- Old answer below (phfffft!) ------
You pose several different questions here: one regarding custom buttons in the nav bar of a nav controller, another about assigning multiple views to the nav controller, and one about placing the view in separate XIB files, while maintaining IBOutlet connections and such.
The first one calls for a tab bar controller, which you can customize to look in whatever way you deem fit, even like a nav bar (ADC has ready-to-use sample code, "UIKit Catalog (iOS): Creating and Customizing UIKit Controls", which fits your needs).
The second can be done easily in Interface Builder by following any number of instructions freely available on YouTube, at Apple, and elsewhere on the Internet; you'll find it an extremely intuitive process. If you can drag-connect a tab bar controller to a view controller, you can intuit the rest. Otherwise, Apple has sample code for customizing the navigation or transition between views in a single view controller interface. "State Restoration of Child View Controllers" provides the best structure for what you want (just pull out the restoration-related code, and use the rest).
The third is not intuitive at all; and, as far as I know, there are only a couple of sets of instructions that exist for separating views (or other view controllers and their views) from a parent or top-level view controller. Here's one I haven't tried yet, so I'll be interested to hear how it worked for you:
http://digginginswift.com/2015/08/30/making-reusable-views-in-separate-xibs
The technique I use involves creating a storyboard with a single view controller to start, followed by a new view controller embedded in a container view for each of your intended views; then, deleting the view in each of the child view controllers, which leaves place for the views you set up in separate XIBs. They are connected by setting the File's Owner to the parent view controller. I can send you sample code, if you'd like to try a different approach than the aforementioned website offers.

Is it bad practice to put UIViewControllers in other UIViewControllers?

I know there is the common practice in iOS development of having one UIViewController presented on the screen whose view is loaded from a XIB which will contain all the UIView subclasses in it.
While I was working on a pretty complex widget for an app, I decided to make the widget subclass a UIViewController instead of a UIView. This was because I thought a UIViewController was essentially a UIView with some helper methods around it. Then I could create a XIB for it (I know UIViews can have their own XIBs too), load the views it contains, place ITS view in the presented parent VC's view, and lay it out.
This works fine so far, but I'm wondering if this is bad practice and if I should just subclass a UIView instead and give it a normal NSObject controller. I am seeing some problems with this and I was wondering if anybody could address concerns I have with this approach?
EDIT NOTE: The widget VC does NOT relate to the VC view it is in and is reusable on ANY screen. So the answer is not subclassing the widget VC with the parent VC. The widget is INSIDE the parent VC, but it is NOT a parent VC.
EDIT NOTE 2: I am NOT using Storyboard. Only Autolayout, XIBs, and ARC.
Why can't we have VC's in VC's?
1) Can VC's be simply dropped into ANOTHER VC's XIB and be loaded easily as a subview?
2) I read here: When to use a UIView vs. a UIViewController on the iPhone?
The top answer explains how the VC controls rotation of the screen and laying out the subviews again, so if you add another VC, then the system will automatically think that THAT is the main VC and will attempt to rotate it instead, causing problems. Is this true? Or is he just talking about if you somehow got into a state where 2 VC's were "presented"? I wasn't sure if his answer applied to VC views that were SUBVIEWS of other VC views.
3) In general is this good practice? It certainly seemed more reasonable as it made loading the subview VC's view much easier.
Thanks!
It's absolutely fine. The answer to your problem is ContainerView.
Container View defines a region within a view controller's view subgraph that can include a child view controller. Create an embed segue from the container view to the child view controller in the storyboard.
You almost got it right. Yes, it's good to make a view controller for what you needed. But you shouldn't just add it's view to the parent view, you should also add the view controller as a child view controller of the first view.
You can add many views controllers as child view controllers of a view controller.
You can learn more about this here.

Best practice to develop common header view across all controllers/windows in iOS app

I'm keeping on developing an iPhone app (rigth now native one) and I would need to use a common "header" for all views but I don't want/need a UINavigationBar and prefer much more have a common "partial view". It will have some actions to perform but always the same ones (showing notifications panel, basically). It should be something like you can see in the screenshots.
I don't need (I feel) delegation because the controller's view can handle notifications and show them when user clicked the customize button.
I don't mind to use a Nib o make the view hardcoded but I'm not sure how I must make an instance of the view or the controller that handles it within each app tab (I'm using UITabBar as navigation control).
From my point of view it doesn't exist a way to get a common controller to call wherever needed; you just can use some method to present new controller as modal o push it out and I think that is not what I'm looking for.
Any idea is welcome. Thanks
Create a custom view controller with 2 subviews. Subview 1 is the header. Subview 2 is the container view where child view controllers are displayed (your tab bar controller in this case).
Your custom view controller could be the delegate of the tab bar controller if you want, so it can be notified when the tabs change and update anything on the header view.
Well, finally is have used the solution I found on the link http://patientprogrammer.wordpress.com/2012/03/12/re-usable-subviews-in-ios/
I have created a Nib with a view controller and then, in the main window I have added two view, the top one subclasses the view controller for the Nib view and it is rendered automatically when app is launched without a single line of code within "main" controller. See the screenshots for more detail:
Thank you very much for your help

Does my Storyboard contain my views?

I am worried I am missing some high level understanding of Objective-C. Could someone clear this point up for me please?
When using storyboard I put ViewController on the design area. For example 'MyDetailViewController'. I then put labels, text boxes and such in this view controller.
Is this my view?
Am I being stupid and putting my controls within my controller instead of creating a separate view and connecting this to the controller or is the area I am working in within the storyboard essentially become my view and assigning a UiViewController class to the controller is correct?
Thank you for helping me out.
It is both your view controller and its view. If you look closely you will see that they are two different things, and that they are connected by an outlet (the view controller's view outlet). This is the usual arrangement in a storyboard (a view physically inside its view controller in the canvas), though it is not absolutely required — if you wanted to, you could have this view controller get its view in some other way, e.g. from a .xib file.

How to subview a UITableViewController within another Controller using Storyboards

I have encapsulated all my table view logic on a UITableViewController that is linked to a view. This was done using storyboards.
I would like to embed this logic and view within another view controller / view (kind of like a header information with a scrollable table beneath.)
I have the following components:
CustomViewController which is linked to a UIView (dragged in from storyboard)
CustomTableViewController which is linked to a UITableView (dragged in from storyboard)
Essentially I am trying to mimic the scenario of the Stopwatch in the iOS clock app
What is the beast approach to this?
How is it done programatically?
Can this be done on the storyboard somehow?
Any help would be greatly appreciated. Thanks
Ok figured it out. This solution is iOS 5 specific since this feature was added there. This method works with storyboards.
Setup: The intention is to host one view controllers view and logic within another controller.
Since there is no intrinsic way to reference the child view controller in the storyboard, we need to give the view controller a name. This can be done by filling out the "Identifier" attribute on the controller in the storyboard. NOTE: Make sure you are giving the controller the identifier and not the controllers view.
Instantiate the controller you want to aggregate. This can be done from the hosting controller.
UIViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"ControllerIdentifier"];
Add the child controller to the parent controller
[self addChildViewController: controller];
Add the child controllers view to the parent controllers view. Note if you have a place holder view in the parent controller you wish to add the child view to, then this is where you do it. Here I add it the a UIView called stage in the parent controller.
[self clearStage];
[self.stageView addSubview:controller.view];
presentedController.view.frame = self.stageView.bounds;
And that is it. Pretty simple. I have used it successfully with switching controllers and view in a home made tab control. The sub controller enlists its views in the view lifecycle, so the viewDidLoad, etc all work as expected in this child view controller.
Hopes this helps someone.

Resources