present a storyboard UIViewController from a UIScrollView subview - ios

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];

Related

MMDrawerViewController objective-c push to navigation view controller

i am beginner iOS dev, I have my app with many controllers.
After login on LoginViewController (LoginViewController has segue relation with NavigationViewController) I do init MMDrawerViewController with this code:
-(void)initSidebarController{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *leftView = [mainStoryboard instantiateViewControllerWithIdentifier:#"LeftViewController"];
UIViewController *centerView = [mainStoryboard instantiateViewControllerWithIdentifier:#"CenterViewController"];
UINavigationController *leftNav= [[UINavigationController alloc]initWithRootViewController:leftView];
UINavigationController *centerNav= [[UINavigationController alloc]initWithRootViewController:centerView];
appDelegate.drawerController= [[MMDrawerController alloc]initWithCenterViewController:centerNav leftDrawerViewController:leftNav];
appDelegate.drawerController.openDrawerGestureModeMask = MMOpenDrawerGestureModePanningCenterView;
appDelegate.drawerController.closeDrawerGestureModeMask = MMOpenDrawerGestureModePanningCenterView;
appDelegate.window.rootViewController = appDelegate.drawerController;
[appDelegate.window makeKeyAndVisible];
}
Now I want to push DishesViewController on NavigationViewController when user didSelectRowAtIndexPath .
How can I do this correctly ?
Thanks
Go to the storyboard, select dishesViewController and select the identity inspector from the left pane and in the StoryboardID enter "dishesVC" then use this code :
CateringDishesViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"dishesVC"];
[self.navigationController pushViewController: animated:YES]
Please follow below step, I am sure it will work for you.
1) Get top ViewController (Reference link).
2) If your MMDrawerController library configure is proper then you will get MMDrawerController as a top view controller.
3) Then find center UINavigationController
4) By using center navigation controller you can to new view controller into stack.
If you don't able to do it then provide sample source code with us. So we can provide exact solution.

Open Storyboard on top of previous view

I have created storyboard which I want to open on top of another view or in childView so that when I close or destroy this view of storyboard the earlier view on which the storyboard is opened remains the same.
When I run the following code:-
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main_iPad" bundle:nil];
ViewController *detailViewController = [storyboard instantiateViewControllerWithIdentifier:#"neolick"];
[[UIApplication sharedApplication].keyWindow setRootViewController:detailViewController];
First, the storyboard opens but I don't know whether it opens on top of previous view or it destroys the previous view & then open.
Second, the functions needed on that storyboard runs automatically which is as I want but how these things are working.
If anyone can help me understand the above code and its working.
NOTE: I cannot call the earlier view again in same state because of some reason.
Thanks in Advance!!
Here you are setting root view controller
it will not keep your back screen as it is what you want
If you want to keep current screen and show other screen on that
you have two approaches
1) Present ViewController
2) Push View Controller
1) Present ViewController
for this you can present your screen on top of other screen which is visible
for example
- (IBAction)btnNextTapped:(id)sender {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main_iPad" bundle:nil];
ViewController *detailViewController = [storyboard instantiateViewControllerWithIdentifier:#"neolick"];
[self presentViewController:detailViewController animated:true completion:nil]
}
2) Push View Controller
For that you need NavigationController and need to push your ViewController from current visible screen
i.e
[self.navigationController pushViewController:vc animated:true];
EDIT
as per discussion you need to find current top view controller then you should present it
Add this method below your method
- (UIViewController*) topMostController
{
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
return topController;
}
And Replace this method with code
- (void)goToNewPage:(CDVInvokedUrlCommand*)command
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main_iPad" bundle:nil];
ViewController *detailViewController = [storyboard instantiateViewControllerWithIdentifier:#"neolick"];
[[self topMostController] presentViewController:detailViewController animated:true completion:nil];
}

How to open new view controller after click button?

I added one ViewController to my project and created one class.
After I bind this class to my ViewController.
In another controller I have method:
- (IBAction)login:(id)sender {
// How here I can do redirect to controllerViewController
}
There are two ways to push view controllers in the application.
1) by Segue
2) By View controller identifier
1) By Segue :
[self performSegueWithIdentifier:"SegueIdentifier" sender:self];
2) By View controller identifier :
Yourclassname *gotoYourClass = [self.storyboard instantiateViewControllerWithIdentifier:#"ViewControllerIdentifier"];
[self.navigationController pushViewController:gotoYourClass animated:YES];
- (IBAction)login:(id)sender {
ViewController *vc = [[ViewController alloc]initWithNibName:#"ViewController" bundle:nil];
[self presentViewController:vc animated:YES completion:nil]; }
In the storyboard give your view controller an identifier (under the Attributes Inspector) then use the following code, to bring that view forward.
IF YOU WANT TO USE PUSH THEN USE THIS CODE
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"STORYBOARDNAME" bundle:nil];
UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier:#"VIEWCONTROLLERIDENTIFIER"];
[self.navigationController pushViewController:vc animeted:YES];
IF YOU WANT TO PRESENT THEN USE THIS CODE
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"STORYBOARDNAME" bundle:nil];
UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier:#"VIEWCONTROLLERIDENTIFIER"];
[self presentModalViewController:vc animated:YES];
Note: In UIViewController please enter your view controller name which you want to push into another view.
If you want to comeback to the current ViewController later then use Navigation ViewController or else just use the presentedViewController of self(your current viewController)- no going back business, like they have previously illustrated.
For a simple block of execution(demo or practice) it's all the same but for a project application it completely matters to make the correct choice.

Switching between two UITabBarController?

I'm developing storyboard based app and I'm wondering if I could have 2 TabBarControllers - one is for user not logged in and another one for user logged in. Can I swap NotLoggedInTabBarController to LoggedInTabBarController on login button action?
If you add a Restoration ID to your viewControllers in the storyboard (identity inspector) you can instantiate a controller by calling the method instantiateViewControllerWithIdentifier:
In your case, maybe i would have instantiate a parent view controller, and when wanting to swap of tabBarcontroller, I would have called
[parentViewController.storyboard instantiateViewControllerWithIdentifier:#"tabBarController2"];
And then change controller displayed.
(Not tested, just some ideas...)
You can add IBAction to your button with check of this condition and instantiate needed controller.
ViewController *viewController = nil;
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
YourViewController *viewController = nil;
if ([userManager isLoggedIn]) {
viewController = (YourViewController *)[storyboard instantiateViewControllerWithIdentifier:#"LoggedInViewControllerIdentifier"];
} else {
viewController = (YourViewController *)[storyboard instantiateViewControllerWithIdentifier:#"NotLoggedInViewControllerIdentifier"];
}
[self.navigationController pushViewController:viewController animated:YES];
in your storyboard you'll have to set storyboard id in Identity inspector
EDIT
If you are not using navigationController to route to correct logged/notlogged controllers then your could do sth like that:
MyAppDelegate *appDelegate = [UIApplication sharedApplication].delegate;
[appDelegate.transitionController transitionToViewController:viewController
withOptions:UIViewAnimationOptionTransitionFlipFromRight];

Passing managedObjectContext via presentViewController

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];

Resources