Add subview to another view - iphone

With two ViewControllers, MyView 1 and MyView 2, is there possible to add a subview to MyView2 from MyView1.m?
I have tried:
MyView2 * screen = [[MyView2 alloc]initWithNibName:nil bundle:nil];
[screen.view addSubView:mySubView];
But my new instance of MyView 2 has no connection to the 'visible' ViewController on MyView2, right?
To clarify, the ViewController that is showing, is MyView1. I want MyView1 to be able to add a subview to the MyView2 view.
Thanks

I think you're confusing viewControllers with views, or at least your question is. Maybe it's something like this you're looking for -
MyViewController2 *myViewController2 = [[[MyViewController2 alloc] initWithNibName:nil bundle:nil] autorelease];
[myViewController2.view addSubView:mySubView];
// add any other views to myViewController2's view
[self.view addSubView:myViewController2.view]; // adding the view to VC1's view
If you want to be able to continue adding stuff throughout MyViewController1, you should declare either myViewController2 or its view as a retained property.

You could have MyView1 controller save some information in a common object in your app so that when MyView2 reappears it can add the subview to its view if needed.

Assuming MyView2 is a subclass of UIViewController, there is no addSubView: method on the viewcontroller itself. Instead, you want to add the subView to your view controller's view, like this:
[screen.view addSubview:mySubView];

try this,
[MyView1.view addSubView:MyView2];
[self.view addSubview:MyView1];

Related

addSubView to viewController.navigatorController

I have a viewController and I am trying to add a subview to it such that it will cover the whole screen, however this has a navigationController in it so that adding a subView always adds it below the navigation bar, is there a way to simulate a presentModalViewController in cases like this?
You can add the subview to the view controller and then hide the navigation controller from the top or you could still push it to the navigation controller and then just remove the navigation controller from the top again and then you could use pop to go back and forth.
the code to push a view controller is
if(!self.YOURVIEWCONTROLLER){
self.YOURVIEWCONTROLLER = [[YOURVIEWCONTROLLER alloc] initWithNibName:#"YOURVIEWCONTROLLER" bundle:nil] autorelease];
}
[self.navigationController pushViewController:self.YOURVIEWCONTROLLER animatedLYES];
and on the next NEXTView.m add
[self.navigationController setNavigationBarHidden:YES];
remember to create an instance of YOURVIEWCONTROLLER in the .h file. Or you could do a simple
[self.view addSubview:NEWVIEW];
[self.navigationController setNavigationBarHidden:YES];
at least at bear minimum the line for making the navigationController hide is there.
I seem to recall once having a similar problem, and I seem to recall the solution was to add the subview to the navigation controller (as the view controller is already a sub view of the navigation controller) rather than adding it to the view controller.
I recently have similar problems and after spending 5 to 10 min I get the exact solution...
According to my solution I simply add my custom UIView to subview of navigationController.view
Like This :-
[self.navigationController.view addSubview:popOver];
popOver - Your custom UIView
Happy Codding :)
Add the view to the superview of the navigationController's view.
[navigationController.view.superview addSubview:viewController.view];
Perhaps you could hide the navigation bar when you add the subview. I have a method on my ViewController that looks like this:
self.navigationController.navigationBarHidden = YES;
UIView *v = [[UIView alloc] initWithFrame:self.view.frame];
v.backgroundColor = [UIColor redColor];
[self.view addSubview:v];
When that code executes, my navigation bar disappears and a full screen red view replaces it.

Multiple root view controllers for UINavigationController?

I'm trying to switch between several table views as the root of a navigation controller. Depending on the settings of my app, I want to use different sets of data with different methods, and prefer to have these encapsulated in separate classes.
My thought was to set a view manager class (UIViewController) as the root view controller of the navigation controller. In the view manager we check the settings to see which view we want to load:
if([application_mode intValue]==APPLICATION_MODE_A){
AViewController *aView = [[DeviceTableViewController alloc] init];
[self.view insertSubview:aView.view atIndex:0];
}
else if([application_mode intValue]==APPLICATION_B){
BViewController *bView = [[BViewController alloc] init];
[self.view insertSubview.bView.view atIndex:0];
}
That does in fact insert the appropriate view into the view manager, at the cost of a white bar at the top of the inserted view and no info on the navigation bar, ie the subview is not connected to the navigation controller.
What's the proper way to do this? I'd really prefer not to have one ginormous table view!
Where do you set your navigationController's rootViewController? Can't you just set it to an AviewController's object or an BViewController's object at this time ? You may not need an intermediate UIViewController
I would do at the beginning :
//navigationController comes from a Xib or previous code
if([application_mode intValue]==APPLICATION_MODE_A){
AViewController *aView = [[DeviceTableViewController alloc] init];
navigationController.rootViewController = aView;
[aView release];
}
else if([application_mode intValue]==APPLICATION_B){
BViewController *bView = [[BViewController alloc] init];
navigationController.rootViewController = bView;
[bView release];
}
Since there is no view controller containment, I like the approach outlined in Jonah William's blog:
http://blog.carbonfive.com/2011/03/09/abusing-uiviewcontrollers/
You can't effectively place a view controller inside another; instead, we create something with similar lifecycle methods (viewDidLoad, viewDidAppear, etc) and forward those methods from the parent to the child. This 'psudo-viewcontroller' has a view property that we add as a subview to the parent's view, using UIView addSubView
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIView_Class/UIView/UIView.html#//apple_ref/occ/instm/UIView/addSubview:
With this approach, we can encapsulate view elements, switch them out dynamically in a view controller, place several within a single view controller, etc. This way they can be considered separately from your navigation stack. It's a bit of work, but the cleanest UI encapsulation approach in iOS 4 in my opinion.

Display UIViewController as a popover

I want to display a UIViewController as a small popover over an other UIViewController.
The UIViewController should be display modal, but not take the whole screen.
It should just show up on a lower third of the screen...
Can somebody point me to a tutorial or give me some hints to start on this?
I googled for over one hour, but could not find anything, that helps me :(
Thanks for your help,
Stefan
Just discovered that this question is still unanswered ... You have multiple options to achieve such a thing running on iPhone:
Depending on the situation, I think I would just go with a UIViewController subclass loading from a NIB that you configured to show a screen-sized view with the backgroundColor property set to [UIColor clearColor]. Add whatever subviews you want to display as a popover to that view at the position you want (e.g. lower third of screen). You can then present the view controller modally with the UIModalTransitionStyleCrossDissolve to fade it in and even use the background view to intercept touch events to dismiss the modal view.
Another possibility would be to just add the popover's view controller's view as a subview to the main view controller's view. You can use UIView's animation class methods to animate the transition.
this might help.
you have to declare popOverController in the header and make it a property as well as synthesize it.
if([self.popOverController isPopoverVisible])
{
[self.popOverController dismissPopoverAnimated:YES];
return;
}
UINavigationController *favNav = [[UINavigationController alloc]
initWithRootViewController:favoritesView];
//favoritesView is an outlet to the VC Favorites
//make a nav controller with the root view an outlet to the view you want to present.
self.popOverController = [[[UIPopoverController alloc]
initWithContentViewController:favNav] autorelease];
[popOverController presentPopoverFromBarButtonItem:revealFavorites permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES]; //revealFavorites is the button i press to show the favorites popover
favoritesView.view.frame = CGRectMake(10, 10, 310, 320); //set the frame
if (![self.popOverController isPopoverVisible]) {
[favNav release];
}
}

UIScrollView with multiple UIViewControllers

i have one scrollview and 4 UIviewcontrollers with xib files now i want to add 4 viewcontrollers to scrollview
and also the scroll is enabled for four viewcontrollers
any one know this plz answer this problem
Just add them. What's the problem?
// this loads a view controller from a nib
controller = [[UIViewController alloc] initWithNibName:#"YourNibsName" bundle:nil];
// this adds the viewcontroller's view to the scrollview
[scrollView addSubview:controller.view];
// place the subview somewhere in the scrollview
CGRect frame = controller.view.frame;
frame.origin.x = 600;
controller.view.frame = frame;
// don't forget to release the viewcontroller somewhere in your dealloc
[controller release];
Do this for all your four controllers.
yes, you can just add the views of the viewcontrollers to your scrolling view, but remember that you are rolling your own equivalent to a UITabBarController or UINavigationController and so you have some responsibilities:
When you alloc init your vc from a nib the vc will get its viewDidLoad method called.
But when you put the vc.view into your scrollview YOU need to call [vc viewDidAppear:YES] (and also call viewWillAppear just before if your vc uses it).
Be careful with things like presenting modal view controllers from your vc as this may not work as you expect.
Peter
I realize that it's quite an old question. But now you can use UIPageViewController.

UIViewController: set self.view to my view or add my view as subview?

I have a question about UIViewController's subview, I created a UIView subclass MainView, which has the exact size of the screen, I wonder which is a better way of adding MainView, consider the following factors:
1 As MainView has same size as the whole screen, the MainView itself may have subviews, but there is no views at the save level as MainView(ie I don't need to add other subviews to self.view).
2 If I use self.view = mainView, do I put the code in loadView(as the viewDidLoad method means the view(self.view) is already loaded)? I see the loadView method is commented out by default, if I add the code to this method, what other code do I need to put together(e.g. initialize other aspects of the application)?
3 If I add mainView via [self addSubview:mainView], are there actually two off screen buffer? One for self.view, one for mainView, both has same size as the screen and one is layered on top of the other(so it wastes memory)?
Thanks a lot!
I'm not sure I completely understand what you're asking, but I'll try to answer a few of the questions you have.
First of all, if you have multiple UIViews on the screen they are all loaded into memory. You have to do -removeFromSuperview and release them to get the memory back.
You can assign your UIView as the UIViewController's view. For example:
MainView *mainView = [[MainView alloc] initWithFrame:CGRectMake(320.0, 480.0)];
self.view = mainView;
[mainView release]; //since the .view property is a retained property
in that case, you have have the view's initialization code in the -init method. Just redefine it like:
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
//initializations
}
return self;
}
You must implement loadView if you did initialize your view controller with a NIB.
UIViewController takes care of sizing its "main" view appropriately. This is all you need to do:
- (void)loadView
{
UIView* mainView = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
self.view = mainView;
}
I'd solve all of this by doing it in a xib! If you create a UIView in your xib, you can then change it's class (when you select the UIView there should be a text field in the Class Identity section of the Identity inspector* - type 'MainView' here!)
Then, create your view controller by calling
myViewController = [[MainViewController alloc] initWithNibName:#"MyNibName" bundle:nil];
That should solve your problems; it's the main subview of your view controller (directly accessable from self.view) and you don't need to worry about memory usage, there's only one view :)
Sam
NB * Click tools -> Identity Inspector. I didn't know it was called this until I had to write this answer!
Yes, the first code-snippet shown above is the "standard" approach, AFAIK, when not using (evil!) NIB files -- i.e. when alloc'ing your view in-code, via loadView.
Note it seems one can also get away with the following, instead of hard-coding the screen-rect size:
UIView *myView = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
self.view = myView;
[myView release];
Note you definitely want to do the [myView release] call since, indeed, as pointed out above, self.view (for UIView) is a retained property.
Cheers, -dk
Perhaps the most important thing to do is make sure you have the following:
self.view.userInteractionEnabled = YES;
While it might not be required all of the time, it fixes the issue where self.view is unresponsive. This issue pops up occasionally.