I am completely new to iPhone development. I have two ViewControllers
ViewControllerA
ViewControllerB
ViewControllerA is the first one and launches with the app.
I have another ViewControllerB now I want to add view of ViewControllerB as subview to ViewControllerA's view when application launches.
Try this
ViewControllerB *vcb = [[ViewControllerB alloc] init];
[self.view addSubview:vcb.view];
A belated answer. I just wrote some words about my solution for this question. It can be found here:
http://blog.nguyenthanhnhon.info/2014/04/how-to-add-viewcontrollernavigationcont.html
You need to declare the object of VC globally .. otherwise you face some issues.
#interface ViewControllerA ()
{
ViewControllerB *viewControllerBObj;
}
-(void) viewDidLoad
{
[super viewDidLoad];
viewControllerBObj = [[ViewControllerB alloc]initWithNibName:#"ViewControllerB" bundle:nil];
[self.view addSubview:viewControllerBObj.view];
}
try this
in "viewDidLoad" method of "ViewController1"
ViewController2 *vc2 = [self.storyboard instantiateViewControllerWithIdentifier:#"ViewController2"];
[self addChildViewController: vc2];
[self.view addSubview: vc2.view];
You can access the view of a view controller by using it's view property. If you have pointers to two view controllers myControllerA and myControllerB then you can add B's view to A's view by using this.
[myControllerA.view addSubview:myControllerB.view];
Add [self.view addSubView:ViewControllerB.view] in the viewDidLoad() of ViewControllerA.
Related
I have a View application with a Single UIViewController. I then add a UITableViewController through the IB, and I am trying to display the UITableViewController through a button press in the UIViewController (my main view). My button press (IBAction) contains the following code through which I am trying to push my UITableViewController view and display it:
DataViewController *dataController = [[DataViewController alloc] initWithNibName: #"DataViewController" bundle:nil];
[self.navigationController pushViewController:dataController animated:YES];
[dataController release];
My DataViewController is not at all getting pushed into the stack and displayed,
Also I have checked that in the code above, self.navigationController=nil
Probably this is the source of the problem. If so, how to rectify it?
Please help.
UINavigationController *navCtrlr = [[UINavigationController alloc]initWithRootViewController:yourfirstviewController];
[self.window setRootViewController:navCtrlr];
navCtrlr.delegate = self;
navCtrlr.navigationBarHidden = YES;
Create navigation controller in appdelegate.m then you can navigate to any uiviewcontroller
You need to actually create a UINavigationController. The navigationController property tells you whether your DataViewController is currently in a UINavigationController's hierarchy; if not (as in this case), the navigationController property returns nil.
I have an App with one MainWindow.xib file. Then I have ViewControllerA.xib and ViewControllerB.xib. My MainWindow.xib have one ViewController that points two ViewControllerA.xib.
On ViewControllerA I have a button and I would like the button, when pressed, to move ViewControllerB onto the screen. How do I do that?
I tried this code, but I think I am missing something:
- (IBAction)btMyButton:(id)sender
{
ViewControllerB * viewController = [[ViewControllerB alloc] initWithNibName:#"ViewControllerB" bundle:nil];
[[UIApplication sharedApplication].keyWindow addSubview:viewController.view];
[self.navigationController pushViewController:viewController animated:YES];
}
My ViewControllerB does appear, but it is squashed at the top of the screen, over the previous view. Any help is greatly appreciated.
Thank you
Remove the second line:
[[UIApplication sharedApplication].keyWindow addSubview:viewController.view];
You are adding the view twice. The 2nd and 3rd lines both cause the view to be added to the view hierarchy in different places.
--update--
If you remove the 2nd line and are not seeing your view then self.navigationController is most likely nil. Try [self presentModalViewController:] instead.
Make sure that the view of controller B has correct hight you should subtract the navigation bar height 44 px and status bar 20 px as well. Those values are for iPhone.
- (IBAction)btMyButton:(id)sender
{
//you should load from the main app bundle
ViewControllerB * viewController = [[ViewControllerB alloc] initWithNibName:#"ViewControllerB" bundle:[NSBundle mainBundle]];
// you don't need the following line
//[[UIApplication sharedApplication].keyWindow addSubview:viewController.view];
[self.navigationController pushViewController:viewController animated:YES];
[viewController release];
}
Update
As the above comment says if you may don't have a navigation controller to push Controller B into. So Add a navigation controller into the main window instead of the view controller and make its root view controller you Controller A.
I hope this helps you,
you will need to remove old viewcontroller from main windows.
- (IBAction)btMyButton:(id)sender
{
//Assuming you declare two Iboutlet controllerA, controllerB mapping with that view as class variable
{
if (self.controllerB == nil)
{
ViewControllerB * viewController = [[ViewControllerB alloc] initWithNibName:#"ViewControllerB" bundle:nil];
self.controllerB = viewController;
[viewController release];
}
[controllerA.view removeFromSuperview];
[self.view insertSubview:controllerB.view atIndex:0];
}
}
This one make me go crazy. I am building an iphone app where the first view is a login view. UIViewController, when the user succesfully logs in i want to display i table view. Somehow i just have big problems doing this.
In my app delegate i load my loginViewController, and then i want from the loginViewController load my listViewController.
What is the logic behind switching to a UITableViewController from a UIViewController?
you'd better to do it in your app delegate and surely NOT add the UITableViewController.view to the UIViewController.view... just add it to the UIWindow and then dismiss the old UIViewController (removeFromSuperView it's view and then release it)
EDIT:
that's how i manage:
i add a method in my appDelegate:
-(void)switchMainView;
and from my UIViewController i just call it with this:
[[[UIApplication sharedApplication] delegate] switchMainView];
in switchMainView i just
remove my UIViewController.view from superview,
release UIViewController,
alloc the UITableViewController and init it, then
add its view to the window app:
-(void)switchMainView{
if (mainView!=nil){ // mainView is the UIViewController
[mainView.view removeFromSuperview];
[mainView release];
mainView = nil;
}
Menu *vc; // Menu is my class, subClass of a UITableViewController
vc = [[Menu alloc] init];
nc = [[UINavigationController alloc] initWithRootViewController:vc];
[window addSubview:nc.view];
[vc release];
}
and then i do the same for going back, eventually
Assuming you already have your custom UITableViewController created:
YourTableViewController *vc = [[UITableViewController alloc] initWithStyle:...];
[self presentModalViewController:vc animated:YES];
[vc release];
you can use either i do'nt think there is a major impact but definitely they might have some advantage/Disadvantage over other..
for better understanding read the below tutorial.
http://cocoawithlove.com/2009/03/recreating-uitableviewcontroller-to.html
I have a my views and controllers set up like so.
A Tab/Bar controller
Within 1. is a root view controller
within 2. is a programmatically created navigation controller, that is displayed as a subview in the root view controller.
What I am trying to do is access the top tab bar/navigation controller so that i can push a view onto it.
I tried parentViewController but all it did was push the view onto the programmed nav controller.
any suggestions?
This is how i set up my root view controller:
-(void)viewDidAppear:(BOOL)animated{
NSLog(#"ROOT APPEARED");
[super viewDidAppear:animated];
WorklistViewController *worklistController = [[WorklistViewController alloc]initWithNibName:#"WorklistView" bundle:[NSBundle mainBundle]];
UINavigationController *worklistNavController = [[UINavigationController alloc] initWithRootViewController:worklistController];
worklistNavController.navigationBar.barStyle = UIBarStyleBlackOpaque;
worklistNavController.view.frame = watchlistView.frame;
[worklistNavController.topViewController viewDidLoad];
[worklistNavController.topViewController viewWillAppear:YES];
[self.view addSubview:worklistNavController.view];
GetAlertRequestViewController *alertsController = [[GetAlertRequestViewController alloc]initWithNibName:#"AlertsView" bundle:[NSBundle mainBundle]];
UINavigationController *alertsNavController = [[UINavigationController alloc] initWithRootViewController:alertsController];
alertsNavController.navigationBar.barStyle = UIBarStyleBlackOpaque;
alertsNavController.view.frame = alertsView.frame;
[alertsNavController.topViewController viewDidLoad];
[alertsNavController.topViewController viewWillAppear:YES];
[self.view addSubview:alertsNavController.view];
}
A nested ViewController (ie, inside a view controlled by a ViewController that's actually on the NavController stack) doesn't have direct access to the UINavigationController that its parent's view's controller is a stack member of. That's one MOUTHFUL of a sentence, but the sense of it is: you can't get there from here.
Instead you've got to get at the app's NavController via the App delegate.
YourAppDelegate *del = (YourAppDelegate *)[UIApplication sharedApplication].delegate;
[del.navigationController pushViewController:nextViewController animated:YES];
You're using your UIApplication's singleton (contains all sorts of good info about your app), which has a .delegate property pointing to the AppDelegate, and that contains a reference to the NavigationController.
This is how the "Navigation-based Application" Xcode template sets up NavController ownership, anyway. YMMV if you rolled your own--though if you did, you probably wouldn't need to ask this question.
You can use the follow instruccion:
[(UINavigationController *)self.view.window.rootViewController pushViewController:vc animated:YES];
It works for me :D
Have a look at UIViewController's navigationController and tabBarController properties. These will return the corresponding navigationController or tabBarController that the given UIViewController 'belongs' to.
So you can do something like:
[customController.navigationController pushViewController:newController animated:YES];
// Similarly for tabBarController ...
here's my code:
ViewController *vc = [[ViewController alloc] initWithNibName:#"TableView" bundle:nil];
[self.navigationController presentModalViewController:vc animated:YES];
//[self setView:[vc view]];
If I call it, nothing happens. However, if I change it to:
ViewController *vc = [[ViewController alloc] initWithNibName:#"TableView" bundle:nil];
//[self.navigationController presentModalViewController:vc animated:YES];
[self setView:[vc view]];
The view appears just fine (without the transition, of course).
What am I doing wrong? Is there anything special you have to take care of when initializing the view controller? I tried to copy as much as possible from Apple's examples, but I can't get this to work...
Thanks for any input!
-- Ry
You can only present modal view controllers from controllers that have already been shown onscreen (usually through a UINavigationController or UITabBarController). Try creating a UINavigationController, pushing a viewController to it, and then presenting your modal controller. There's a starter project in Xcode that shows how to create a UINavigationController-based flow if you're unfamiliar with it.
One other thing to note: if you haven't pushed the view controller onto a UINavigationController, the .navigationController property will be nil, and messaging it will have no effect.
I encountered the same problem while attempting to show a modal view over another modal view. Ben's answer is correct, and can be implemented like so:
#interface FirstView: UIViewController {
UIViewController *firstView;
}
- (IBAction)showOptionsView:(id)sender;
#end
In the main view class:
- (void)viewDidLoad {
[super viewDidLoad];
firstView = [[UIViewController alloc]init];
[firstView setView:self.view];
[firstView setModalTransitionStyle:UIModalTransitionStyleCoverVertical];
}
- (IBAction)showOptionsView:(id)sender {
OptionsView *optView = [[OptionsView alloc]initWithNibName:#"OptionsView" bundle:nil];
if(firstView != nil) {
[firstView presentModalViewController:optView animated:YES];
[optView release];
}