Call willrotate method for added subview controller - iphone

I have added one view controller to my first view controller as aa subview by using self.view add subview:secondview now when I'll rotate the device
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration;
method calls for only parent view Now I also want to call that method for child view controller so i can make required changes in child view controller also.
So for that what I have to do??
-Thanks in advance.

In WWDC 2011 Session 102 on view controller containment, they mention that a failure to keep one's view controller hierarchy synchronized with the view hierarchy can result in rotation events problems. They explicitly point out that if you just grab a view controller's view and add it as a subview of the main view, without adding the controller, itself, to the view controller hierarchy, you won't get these rotation events. In that WWDC session, they also suggest that if you want to "future-proof" your app, you'll want to manage view controllers properly.
From a pragmatic perspective, this means that as you go from one view to another, that you really should be transitioning the view controllers. Most commonly this means using pushViewController or presentViewControllerAnimated (formerly presentModalViewController). Or you can use view controller containment (see that WWDC session or look at the very brief comments about containment in the UIViewController Class Reference). But don't just grab the view from another view controller and just add it as a subview of the current view.
If you pursue view controller containment, at a minimum, you could add your child view's controller to the hierarchy via:
[self addChildViewController:childController];
[childController didMoveToParentViewController:self];

Related

UIViewController inside UIView not getting rotation delegation

I have a UIViewController's view inside my UIScrollView subclass. The problem is my UIViewController is not getting the willRotate delegate called when I rotate the device. This is probably because UIView does not have a rotation delegate implemented in it. What is the best way to solve this?
Basically the structure is I have a MainViewController in which it has a UIScrollView. Inside this UIScrollView I have a subviews, which is the view of a bunch of UIViewControllers. The issue now is, it's not getting rotation calls when I rotate. One way to deal with this is to delegate from the MainViewController to those respective UIViewController. Is there a better/elegant way to solve this?
I am adding it as a subview from my UIScrollView not my MainViewController and you can't do UIViewControllers containment from a UIView. Correct me if I am wrong
I think you're going against the MVC pattern. You can't have a controller inside a view; instead you should have a controller that mediates the communictaion between the view and the user's input. In your case you could set the scrollview as self.view of the MainViewController, and then add the viewcontrollers views as subviews.
Watch the video that I posted in my comment: https://developer.apple.com/videos/wwdc/2011/?id=102
Here is a short summary of view controller containment, which is the design you are looking for, not combining all your logic into one view controller or using delegation for something that is built into the SDK.
A view controller has a view and provides logic for that view and most likely some of it's subviews.
You might have a complex view hierarchy and complex logic for specific views in that hierarchy that warrant the view to have it's own view controller controlling it and it's subviews.
Say you have a MainViewController and it's view is a UIScrollView (or subclass). Inside that scrollview, you might have an assortment of complex views that warrant their own controller, so you have a class, SubViewController that has the subview of the scrollview as it's view.
SubViewController needs to have rotation and appearance method callbacks working correctly in order to implement your logic for the the subview and handle layout changes.
[mainViewControllerInstance addChildViewController:subViewControllerInstance];
But, wait. The subview is still not in the view hierarchy.
[mainViewControllerInstance.view addSubView:subViewControllerInstance.view];
You have successfully created a valid view controller hierarchy of two view controllers and set up the associated view hierarchy of their views.
You will now have the appropriate callbacks functioning, as MainViewController will forward them to SubViewController.
EDIT:
See the documentation for an over view of view controller containment: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIViewController_Class/Reference/Reference.html

positioning UIViewController containment children

I was reading the documentation:
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.
But in which method should I position the view controller children's view? Say I have two UIViewController in the container and I want one next to the other.. how do I do this?
In one of my articles I demonstrated how to create a simple dashboard app using UIViewController Containment.
http://www.highoncoding.com/Articles/848_Creating_iPad_Dashboard_Using_UIViewController_Containment.aspx
Each of the child view controllers has a view property. You can set the frame of those views when you add them to your own view.
It depends on the context of the situation that you may have. If you need to display all of the children when displaying the view for the first time, then add the view controllers and views in viewDidLoad ( if using a xib or nib) or in loadView ( if done programatically). If you need to show the child view controllers on demand, like after the touch of button, then you can add the child view controller and associated view in a separate method.
You will need to layout the views of the child view controllers as you would layout any other subviews. Remember view controller containment is just another ways of allowing you to modularize your code.
Check out this link which helps explain how to add the child view controllers: Animate change of view controllers without using navigation controller stack, subviews or modal controllers?
Here is a simple sample project that shows how to add child view controllers:https://github.com/toolmanGitHub/stackedViewControllers
Good Luck!

addChildViewController and presentViewController

iOS 5 introduces the concept of custom container view controller and provides API like addChildViewController. Question: can you add a view controller as a child and still present it using presentViewController? Does doing the latter automatically make it a child view controller of the presentingViewController?
That's not how it's supposed to be used.
The parent/child relationship is for when a view controller has subviews that are managed by their own view controllers, for example a UITabBarController, where the parent view controller draws the tabs and the child view controllers draw the content of each tab.
If you present a view controller using presentViewController, it generally takes over the whole screen, or appears in a modal so that the presenting view controller is no longer in control. In that scenario there's no reason for the presenter to be the parent because it doesn't need to cooperate with the presented controller - it just gets out of the way until the presented controller is dismissed again.
Why is it that you wanted to do this? If it's just so that the view controllers have a reference to one another and can pass data, there are other ways to do this (e.g. the delegate pattern, NSNotifications, or even just a property linking the two).

UIViewController in a UIView

Can I load a UiViewController in a UIView in another UIViewcontrller.
suppose UIViewControllerA has a UIView named subuiview. Can I load UIViewControllerB into subbuiview?
Thanks!
Starting with iOS 5
"Container view controllers" have been added in iOS 5. You can add a view controller as a child of another one with addChildViewController:.
You also are responsible for adding its view to its parent's view.
Everything is well documented in the iOS SDK documentation: Implementing a Custom Container View Controller.
To add a child view controller:
childViewController.frame = ...
[self.view addSubview:childViewController.view];
[self addChildViewController:childViewController];
[childViewController didMoveToParentViewController:self];
and to remove it:
[self willMoveToParentViewController:nil];
[self.view removeFromSuperview];
[self removeFromParentViewController];
Prior to iOS 5
It's possible to load another view controller and add its view as a subview of another controller's view.
UIViewController *subController = ...
[self.view addSubview:subController.view];
Although it's not recommended by Apple's guidelines:
Each custom view controller object you
create is responsible for managing all
of the views in a single view
hierarchy. [...] The one-to-one
correspondence between a view
controller and the views in its view
hierarchy is the key design
consideration. You should not use
multiple custom view controllers to
manage different portions of the same
view hierarchy.
(from the View Controller Programming Guide)
Your sub-controller won't receive rotation events, or viewWillAppear, viewWillDisappear, etc (except viewDidLoad).
So Apple advises us to use a single view controller managing the entire view hierarchy (but doesn't forbid to use multiple ones).
Each view may still be a custom subclass of UIView. Maybe you don't need another view controller but rather a custom view.
[self addSubview:viewControllerB.view];
try this in the sub view
It has always been problematic to simply use addSubview to add a view controller's view as a subview of another's. It's especially bad when people use it to transition between views, rather than relying upon other, more robust, solutions like presentViewController or pushViewController.
If you really want to add one view controller's view as a subview of another's, iOS5 introduced "view controller containment". Containment is discussed in the View Controller Programming Guide as well as WWDC 2011 session 102. Bottom line, you want to ensure you keep your view controller hierarchy synchronized with your view hierarchy, by calls to addChildViewController, didMoveToParentViewController, etc. See the documentation and the video for specifics.
Well you cant technically load a viewcontroller. You can load a viewcontroller's view as a subview of any view.
You need to also retain the view controller incase you have any actions attached to it. Otherwise it may result in crashes.
addsubview:controller.view is the method you want to look at.

Using navigation controller of superview

I've made a custom view to which I add a custom button. This custom view goes as a subview to yet another view (Kal calendar for iphone) that I push into a navigation controller. Now the button in my custom view is connected to an IBAction in which I am not able to call upon the self.navigationController to pop the current view from.
I've tried the [[sender superview] navigationController] for a hierarchy of superview calls but it doesn't work that way either.
Any ideas please?
Thanks
A view typically has no knowledge of its view controller (and consequently, to its or its superview's view controller's navigation controller) because this would introduce a tight coupling between view and view controller that is usually unwanted and unnecessary.
The easiest way to solve your problem would be to have the view controller instead of the view handle the button's action. If that doesn't work for your design, consider designing a delegate protocol for your custom view and make your view controller the custom view's delegate. The view would then call the delegate method in the button's action method. This latter method is used a lot throughout Cocoa, e.g. by UIScrollView (UIScrollViewDelegate) and UITableView (UITableViewDelegate).