I am trying the "pass the baton" method for passing the managedObjectContext (MOC) thru multiple views. I have it successfully passed to the rootViewController. From there I move to a tabBarController via presentViewController. I can't seem to find a way to pass the MOC when the tabBarController is pushed.
AppDelegate.m
UIViewController *navigationController = (UIViewController *)self.window.rootViewController;
MyViewController *controller = (MyViewController *) navigationController;
controller.managedObjectContext = managedObjectStore.mainQueueManagedObjectContext;
The main view controller is basically a start up screen that will kick you into a login screen or if you are already logged in, to the tabBarController. Below is where I transition to the tabBarController from within the viewDidAppear method.
MyViewController.m
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
UIViewController *mainTabVC = [storyboard instantiateViewControllerWithIdentifier:#"mainTabVC"];
[mainTabVC setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentViewController:mainTabVC animated:NO completion:nil];
The tabBarController in the storyboard has the identifier "mainTabVC".
I've tried lines like
MyTabBarController.managedObjectContext = self.managedObjectContext;
but I get the error Property 'MOC' not found on object of type MyTabBarController even though I do have the property declared in MyTabBarController.h
Could someone show me a line of code that I can throw in this segue to push the MOC to the tab bar controller.
BTW- I'm utilizing RestKit in this app if that changes the way I should be handling this please let me know.
*****Solution********
To make things clear for any other new guys with the same question. I went from this:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
UIViewController *mainTabVC = [storyboard instantiateViewControllerWithIdentifier:#"mainTabVC"];
[mainTabVC setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentViewController:mainTabVC animated:NO completion:nil];
To this:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
MyTabBarViewController *mainTabVC = [storyboard instantiateViewControllerWithIdentifier:#"mainTabVC"];
mainTabVC.managedObjectContext = self.managedObjectContext;
[mainTabVC setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentViewController:mainTabVC animated:NO completion:nil];
Notice the assignment in the third line and using MyTabBarViewController instead of UIViewController in the second line. BIG thanks again to rdelmar!
Your code is somewhat confusing. Is MyTabBarController the class? It looks like mainTabVC is your instance. You should use that rather than the class, and you should change the type when you instantiate mainTabVC to MyTabBarController, instead of UITabBarController. You also don't need to get the storyboard the way you do, you can just use self.storyboard.
MyTabBarController *mainTabVC = [self.storyboard instantiateViewControllerWithIdentifier:#"mainTabVC"];
mainTabVC.managedObjectContext = self.managedObjectContext;
[mainTabVC setModalPresentationStyle:UIModalPresentationFullScreen];
[self presentViewController:mainTabVC animated:NO completion:nil];
Related
I am trying to present a view controller from a UIScrollView subview.
I've tried using AppDelegate window.rootViewController presentViewController: but that gives me the "view is not in the hierarchy!" error.
I want to avoid using addSubview because that breaks MVC and seems to remove the controller's functionality (buttons stop working).
When I use the expected presentViewController method, I get "No visible #interface for "InititalScrollViewSubview" declares the selector "presentViewController:animated:completion:", which I think means that my initialScrollViewSubview is trying to use presentViewController but presentViewController has to come from a UIViewController. UIScrollView is without the presentViewController method.
My code is something like:
-(void)setupTouchIDButtonTapped: (id)sender {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"newViewController" bundle:nil];
NewViewController *myNewViewController = [storyboard instantiateViewControllerWithIdentifier:#"myNewVC"];
//First thing I tried:
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[delegate.window.rootViewController presentViewController:NewViewController animated:YES completion:nil];
//second thing I tried
[self addSubview:NewViewController.view];
//third thing I tried:
[self presentViewController:NewViewController animated:YES completion:nil];
}
The InitialScrollViewSubview has to remain the way it is. Ideally, I'd refactor everything so the InitialScrollViewSubview is another UIViewController but I work for a huge company and the app is way too large :)
Any advice is greatly appreciated!!
Thanks!!
If you are trying to 'embed' a view controller's view within your scrollview then you dont present the view controller. You instantiate it and then add it's view to the view hierarchy.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"newViewController" bundle:nil];
NewViewController *myNewViewController = [storyboard instantiateViewControllerWithIdentifier:#"myNewVC"];
[scrollView addSubview:NewViewController.view];
You will also need to setup the size/frame of the view or setup autolayout constraints so that the view controller is correctly sized.
Try this
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"newViewController" bundle:nil];
NewViewController *myNewViewController = [storyboard instantiateViewControllerWithIdentifier:#"myNewVC"];
AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
UINavigationController * rootNvc = delegate.window.rootViewController ;
[rootNvc pushViewController:NewViewController animated:YES];
I need to present a view controller from app delegate.
When a phone notification comes in, I am able to decide which one of 3 view controllers (named ForumViewController, BlogViewController & NewsViewController) should be presented by analyzing the 'userInfo' in the method 'didReceiveRemoteNotification'.
But when i try to present the appropriate view controller using storyboards or the code below:
self.viewController = [[MembersViewController alloc] initWithNibName:#"MembersViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
Then, the app gives the error 'Warning: Attempt to present whose view is not in the window hierarchy!'. Also it gets stuck on a particular view controller.
Please keep in mind that the view controllers that I am trying to present are not part of the flow when the app starts (the flow is LogoViewController -> SplashViewController -> HomeViewController).
The HomeViewController & MembersViewController are essentially the main menu pages for public & private viewing. Here I have to display something to the viewer.
choice-1
using push
UINavigationController *navController = (UINavigationController *)self.window.rootViewController;
MembersViewController *vc = [navController.storyboard instantiateViewControllerWithIdentifier:#"MembersViewController"];
[navController pushViewController:vc animated:YES];
using present
MembersViewController *root = (MembersViewController *)self.window.rootViewController;
UIViewController *vc = [root.storyboard instantiateViewControllerWithIdentifier:#"MembersViewController"];
[root presentViewController:vc animated:YES completion:NULL];
upadted
UIStoryboard *mainstoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
MembersViewController* pvc = [mainstoryboard instantiateViewControllerWithIdentifier:#"MembersViewController"];
[self.window.rootViewController presentViewController:pvc animated:YES completion:NULL];
Loading a view controller from the storyboard:
[self performSelector: #selector(ShowModalViewController) withObject: nil afterDelay: 0];
-(void)ShowModalViewController{
NSString * storyboardName = #"MainStoryboard";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"IDENTIFIER_OF_YOUR_VIEWCONTROLLER"];
[self.window.rootViewController presentViewController:vc animated:YES completion:nil];
}
Identifier of your view controller is either equal to the class name of your view controller, or a Storyboard ID that you can assign in the identity inspector of your storyboard.
I want to add a navigationcontroller to an existing viewcontroller which is created using storyboard, i have embed it in a navigation controller, but the code for navigating (shown below) is not working even after embed in the navigation controller:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
EditProfileViewController *nextViewController = [storyboard instantiateViewControllerWithIdentifier:#"EPVController"];
[self.navigationController pushViewController:nextViewController animated:YES];
When i have tried to log self.navigationController, it shows null.
Update: It is fine when i am trying with presentViewcontroller , but i
want to push the viewcontroller with navigationController.
I am struggling with this for two days,Please help.
If self is a subclass of UINavigationController, you do not need to refer to the navigationController property. (Note that this won't work if EditProfileViewController is also a subclass of UINavigationController, as you can't push a UINavigationController inside a UINavigationController).
EditProfileViewController *nextViewController = [storyboard instantiateViewControllerWithIdentifier:#"EPVController"];
[self pushViewController:nextViewController animated:YES];
Otherwise, if you don't have a pre-existing navigation controller
EditProfileViewController *nextViewController = [storyboard instantiateViewControllerWithIdentifier:#"EPVController"];
[self presentViewController:nextViewController animated:YES completion:nil];
Using:
UIViewController *vc = [[UIStoryboard storyboardWithName:#"MyStoryboard" bundle:nil] instantiateInitialViewController];
[self presentViewController:vc animated:YES completion:^{}];
But I need to set a BOOL in the initial viewController for that story board.
I have BOOL declared in the .h and an if statement is dependent on it:
if (_boolIsTrue) {
FirstView *firstView = (FirstView *)[storyboard instantiateViewControllerWithIdentifier:#"first_view"];
[self.navigationController setViewControllers:#[firstView] animated:NO];
}
else {
SecondView *secondView = (SecondView *)[storyboard instantiateViewControllerWithIdentifier:#"second_view"];
[self.navigationController setViewControllers:#[secondView] animated:NO];
}
When I try to access it with something like:
UIStoryboard *storybord = [UIStoryboard storyboardWithName:#"MyStoryboard" bundle:nil];
UIViewController *vc =[storybord instantiateInitialViewController];
vc does not give me access to the BOOL.
Not sure what it is that I am not understanding about ViewControllers and Storyboards, but I would really appreciate the help.
Thanks
EDIT AFTER SOLUTION:
Wain was exactly right!
Here's the exact working code since my gaps spanned a couple different concepts. In case it helps someone else:
UINavigationController *nav = [[UIStoryboard storyboardWithName:#“MyStoryBoard” bundle:nil] instantiateInitialViewController];
InitialLockSetupViewController *vc = nav.viewControllers.lastObject;
vc.isBoolTrue = YES;
[self presentViewController:nav animated:YES completion:^{}];
So you have to get the View Controller with the correct type in order to access the var. BUT if it's not set as the initial view controller in the storyboard you have to get it as the root (0-th) view controller on the stack. THEN you have to remember to push the nav controller NOT the view controller.
Thanks again Wain. This was a good lesson!
You're simply not understanding that the compiler needs to know the class type. Currently you're telling the compiler that the class is UIViewController and it obviously doesn't have your custom property. You need to set the class to your custom one, like:
MyViewController *vc = [storybord instantiateInitialViewController];
Also, make sure that you don't call instantiateInitialViewController more than once or you'll have multiple copies of the same class and might use the wrong one...
I have multiple storyboards within my app. I want to pass an object when a new storyboard is opened.
I'am doing this:
UIStoryboard* storyboard = [UIStoryboard storyboardWithName:#"SetupStoryboard" bundle:[NSBundle mainBundle]];
UINavigationController* initialHelpView = [storyboard instantiateInitialViewController];
SetupViewController *setup = (SetupViewController*) [initialHelpView topViewController];
setup.data = self.data;
initialHelpView.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:initialHelpView animated:YES completion:nil];
But when the storyboard is presented the setup.data is nil in viewDidLoad, viewWillAppear etc of the SetupViewController...
Why is that?
I don't see anything wrong with this code. Problem may be elsewhere.