presentViewController not working as I'd like - ios

I have my presentViewController code set up like this:
ProductViewController *vc = [[ProductViewController alloc] init];
[self presentViewController:vc animated:YES completion:nil];
It indeed presents the vc controller, but I'm unable to tap anything on it, it's like a frozen screen. Is it because there is still a view on top of it? Or I shouldn't be using alloc] init?
ProductViewController is an existing view controller (it's actually the root view controller), so basically I'd just like the presentViewController to just go back to the root view controller.
Edit:
I have a ShippingViewController where the user enters name/shipping details.
Then they tap on "Checkout" button that presents the PaymentViewController (which has a navigation bar, all other View Controllers don't).
On the PaymentViewController, the user enters their credit card details and tap the "Pay" button.
If the payment is successful, I wish for ProductViewController (the initial/root view controller) to be presented. Currently if I am just calling dismissViewController, it presents ShippingViewController.

This seemed to take care of my problem:
NSString *storyboardName = #"Main";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController *vc = [storyboard instantiateViewControllerWithIdentifier:#"id"];
[self presentViewController:vc animated:YES completion:nil];

Related

IOS/Objective-C/Storyboard: Prevent ViewController From Launching Modally

I want a viewcontroller to launch using a show transition, not modally from the bottom. Normally when I use the following code that's what happens. However, in this case, it is launching as a modal controller from the bottom up. Is there a switch I don't know about or could something be set in Storyboard that is causing this VC to launch modally from the bottom instead of showing?
UIStoryboard *storyBoard = self.storyboard;
IDImportEventsOnboard *importEvents =
[storyBoard instantiateViewControllerWithIdentifier:#"importEventsOnboard"];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController: importEvents];
[self presentViewController:nav animated:YES completion: nil];
The VC is embedded in a navigation controller.
Should I be using showViewController directly to the targetVC without going through the Nav? Or a pushViewController What is a proper, robust way to show a VC with a show transition?
Thanks in advance for any suggestions.
In the above code you are 'presenting' a new NavigationController from a ViewController. In order to do a push/show transition, that needs to be done on an instance of a NavigationController. If your current ViewController is already in a NavigationController, you can push the new ViewController onto the current NavigationController stack. For Example:
UIStoryboard *storyBoard = self.storyboard;
IDImportEventsOnboard *importEventsVC =
[storyBoard instantiateViewControllerWithIdentifier:#"importEventsOnboard"];
[self.navigationController pushViewController:importEventsVC animated:YES];

Cannot click back button when open view from remote notirication

My iOS application using Objective C. It received a remote notification, when a user click it, it will open a particular view.
This view has a back button in the navigation tab. In normal scenarios can back to root view. However, when I open this view from a notification, cannot back to any view nor leaving the application.
Here is my spruce code:
1. from AppDelegate.m to open a particular view:
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *viewAnnouncement =[storyboard instantiateViewControllerWithIdentifier:#"Announcement"];
self.window.rootViewController = viewAnnouncement;
[self.window makeKeyAndVisible];
Action function to back to previous view (in viewClass.m):
- (IBAction)onBtnBackClicked:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
I believe the problem is, when I open this view from a notification, no parent view to let it back to. Can anyone help me, when user open this view from a notification, whether it goes to a root view or back to the previous opening app
EDIT : The previous answer didn't take in count the fact that you were in AppDelegate. Maybe this answer is better.
Turn your [self dismissViewControllerAnimated:YES completion:nil]
into :
UINavigationController *navigationController = [[UINavigationController alloc] init];
UIViewController *yourPreviousVC = [[UIViewController alloc] init];
[navigationController pushViewController:yourPreviousVC animated:YES];
If I'm wrong or if I missunderstood the question, do not hesitate to correct my answer.
Try this
Announcement *annouce = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"Announcement"];
HomeVC *home = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"HomeVC"];
[((UINavigationController *)self.window.rootViewController) setViewControllers:#[home,annouce] animated:YES];
And If app already open and you want to go previous page
Announcement *annouce = [[UIStoryboard storyboardWithName:#"Main" bundle:nil] instantiateViewControllerWithIdentifier:#"Announcement"];
UIViewController *visibleView = ((UINavigationController *)window.rootViewController).visibleViewController;
[((UINavigationController *)self.window.rootViewController) setViewControllers:#[visibleView,annouce] animated:YES];
I found the solution. My app has multiple views which I can go from a navigation list. When I want to back to main view, I just dismiss the current view.
Cuurently, a view is opened when I click a notification and I can't simply dismiss this view, Coz it considered as root view.
What I did to solve it, I connect my view (Announcement) by segue to main view, and set an identifier (for example: "leaveAnnouncementPage". Then, in your class just call this function in back button's fnction to back to the main view:
[self performSegueWithIdentifier:#"leaveAnnouncementPage" sender:self];
Here is also some useful links:
First
Second
Thank you guys for your help, and all the best

Going back and forth between UIViewController while keeping the states of the views

I have two view controllers, PlayViewController and ShopViewController.
The goal is to go from PlayViewController to ShopViewController, and back.
To go to the shopController I use this code:
UIStoryboard* mainStoryBoard = [UIStoryboard storyboardWithName:#"MainStoryboard_iPhone" bundle:nil];
ShopViewController* vc = [mainStoryBoard instantiateViewControllerWithIdentifier:#"ShopViewController"];
vc.modalTransitionStyle=UIModalTransitionStyleCrossDissolve;
[vc setGameLevelManager:[[playViewController getCentralUIManager] getGameManager]];
[vc setUIViewControllerOrigin:nil PlayerViewController:playViewController];
[playViewController presentViewController:vc animated:YES completion:nil];
The code above works, user jumps from the PlayViewController to the ShopViewController.
Now when jumping back from the ShopViewController to PlayViewController I use the following code:
playViewController.modalTransitionStyle=UIModalTransitionStyleCrossDissolve;
[self presentViewController:playViewController animated:YES completion:nil];
The Code above does go back to the PlayViewController, but call for the viewDidLoad and re-initiate the view from the beginning. Thing is that when i call ShopViewController from PlayViewController, I have additional window shown in the View, namely the LevelFailure view. When ViewDidLoad, it completely forget about what was displayed when the user went to ShopViewController.
I am sure there is a way to go back to PlayViewController and have the states , and views back how they were , but I could not identify the approach yet.
If you would have any thoughts about the matter, there would be more than welcome!

Difficulties changing between viewControllers in xcode

I have 3 different viewControllers. first one is the main page where you will see many thumbnail of images. Second controller will only open when an image is clicked. Last ViewController is the login which opens when the user is not logged in but trying to view the second controller or clicked login from the main controller. In the login controller I have a back button to go to main page. Remember the user can access login from two different ways. by clicking on the image or clicking login in the main controller directly. So the issue is the back button does work properly. When the login page is accessed from the main controller directly, then the back button works fine it takes you to the main page. However, if you click on any of the thumbnails the second controller will try to open but since your not logged in the login page will show and when you click the back button to send you to the main controller, it won't go to main instead it will reload the same page and you kind of stock in a loop you have to login or exit the app. any ideas why?
The First ViewController Identifier is set to "mainImages".
- (IBAction)backToMain:(id)sender {
[self dismissViewControllerAnimated:NO completion:nil];
NSString * storyboardName = #"MainStoryboard";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController * MI = [storyboard instantiateViewControllerWithIdentifier:#"mainImages"];
UINavigationController *navController = self.navigationController;
if (navController) {
[navController pushViewController:MI animated:NO];
}
}
I also tried this but no luck:
[self dismissViewControllerAnimated:NO completion:nil];
UIViewController * MI = [self.storyboard instantiateViewControllerWithIdentifier:#"mainImages"];
[self presentViewController:MI animated:NO completion:nil];
Try this if you are presenting as modal:
- (IBAction)backToMain:(id)sender {
[self dismissViewControllerAnimated:NO completion:^{
UIWindow *window = [[UIApplication sharedApplication].windows firstObject];
UINavigationController *nav = (UINavigationController *)window.rootViewController;
[nav popToRootViewControllerAnimated:YES];
}];
}
If you need to "go back" from the login view to any other view (in this case 2 of them), you should try using a Modal Segue, a modal segue lose the navigation controller view stack but allow you to dismiss the login view and go back to you last view.
On the first (or thumbnail images view controller) show your new modal view as this:
UIViewController *modalViewController = [[UIViewController alloc] init];
[self presentViewController:modalViewController animated:YES completion:nil];
And then, to dismiss (on login view controller):
- (IBAction)backToMain:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}

How to call a View Controller from not related View Controller programmatically?

as you see on the image, on the normal case I click the button1 to call the second view and then I click the button2 to call the last view, and in a particular scenario I want to click the button1 to call the last view.
I added this on the methode viewDidLoad:
if(condition)
[self performSegueWithIdentifier:#"thirdview" sender:self];
but it is not working, any help please.
thank you.
You need to add a segue from ViewController1 to Viewcontroller3.
But if you do this with many viewControllers then it becomes messy, I call it the spaguetti segues.
The alternative is to present that viewController modally.
Example:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
ViewController3 *viewController =
[storyboard instantiateViewControllerWithIdentifier:#"viewController"];
[self presentViewController:viewController animated:YES completion:nil];
(make sure you give ViewController3 a storyboardId)

Resources