Difficulties changing between viewControllers in xcode - ios

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

Related

Having trouble in PresentDismiss & NavigateViewController push/pop

I have the whole app embedded in UINavigationController. Now there is the Home Screen that has several modules for user to choose. Now, when the user clicks on the module it is NAVIGATED and if user desires to choose some another module from any other modules available, there is a button in navigation bar, which PRESENTS the HomeViewController modally on top of the current module and then user can choose any module from there which will NOT BE PRESENTED instead they will NAVIGATE.
Now what I have done is made a delegate called navigate on HomeViewController and will be override by viewcontrollers of each module and it will take the reference of the new ViewController with it. Then when this method is called I have first dismissViewController the HomeViewController and then navigated to the new ViewController that I have the reference.
Now, what the real issue is that SOMETIMES there is a jerk when navigating from one module to other and sometime it works fine. That why I am not able to debug also. The jerk is that when a module is clicked from HomeViewController, the home screen disappears and the appears again and then it actually navigates.
The code for navigating to a module from HomeViewController is
RadiusSearchViewController *rad = [self.storyboard instantiateViewControllerWithIdentifier:#"RadiusSearchViewController"];
[self.delegate navigate:rad];
This navigation overrided method in all modules is
-(void)navigate:(UIViewController*)uiViewController{
NSLog(#"inside navigate method");
[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
[self.navigationController pushViewController:uiViewController animated:YES];
}
I assure you that it is coming in this method.
Now the code that presents the HomeViewController modally is
ViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"HomeVC"];
vc.view.backgroundColor = [[UIColor whiteColor]colorWithAlphaComponent:0];
vc.delegate = self;
vc.providesPresentationContextTransitionStyle = YES;
vc.definesPresentationContext = YES;
vc.modalPresentationStyle = UIModalPresentationOverCurrentContext;
vc.fromOutside = true;
NSLog(#"Presneting...");
[self presentViewController:vc animated:NO completion:nil];
The reason for PRESENTING and NOT NAVIGATING the HomeViewController is that it comes on the top of the current module in transparent form which is necessary.
REMEMBER: It happens sometimes not all of the time. Like you can say half of the times.
[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
[self.navigationController pushViewController:uiViewController animated:YES];
this should be changed to...
[self.presentedViewController dismissViewControllerAnimated:YES
completion:^{
[self.navigationController pushViewController:uiViewController animated:YES];
}];
this will make sure navigation view controller will be called after dismiss is done. check and see if it solves your problem.

(UINavigationController) PushViewController fails after PresentViewController

I am building an application in which the main content is a navigation controller. However, the first time the app loads, I am pushing another view controller on top of that controller (the user has to register etc). This has to be separate from the navigation controller so the user cannot just backtrack. Currently, Navigation through my navigation controller works only on times when the other view controller isn't loaded.
The code to load the 'register' VC if it is needed:
NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
if ([prefs objectForKey:#"id"]) {
}
else {
RegisterViewController * rvc = [storyboard instantiateViewControllerWithIdentifier:#"registerVC"];
[self.navigationController presentViewController:rvc animated:NO completion:^(void){}];
}
On completion of registration:
[viewCtrl dismissViewControllerAnimated:NO completion:^(void){
NSLog(#"VIEW DISMISSED PROPERLY");
}];
Note: viewCtrl is the viewController pushed on. Also On times when the navigationcontroller stops working 'view dismissed properly' is called. So I know that the view is being dismissed.
Finally, code to push another page normally onto the navigation controller:
ContactViewController * cvc = [self.view.storyboard instantiateViewControllerWithIdentifier:#"contactVC"];
[self.view.navigationController pushViewController:cvc animated:NO];
Just to reiterate, ContactViewController only loads if the registration page wasn't loaded.
Thanks in advance.
You should push other ViewController after dismiss finished:
[viewCtrl dismissViewControllerAnimated:NO completion:^(void){
NSLog(#"VIEW DISMISSED PROPERLY");
ContactViewController * cvc = [self.view.storyboard instantiateViewControllerWithIdentifier:#"contactVC"];
[self.view.navigationController pushViewController:cvc animated:NO]
}];

How to pop back viewController from SWRevealViewController?

In my app after pressing the login button in my loginViewController, it push to front viewController of my SWRevealViewController. In my RearViewController I have the sign out button. When I press it it should pop to the back viewController again (LoginViewController). But even though I set the button click event like this it doesnt navigate to the loginViewController.
-(void)signOutClick :(id)sender
{
[self performSelectorInBackground:#selector(moveToLoginView) withObject:nil];
}
-(void)moveToLoginView
{
[self.navigationController popToRootViewControllerAnimated:YES];
}
But when I swipe the view it gose to the back view.I want to disable that swipe feature to the back view. And I want to go to the back view when click on the sign out button in my RearViewController. How can I do that? Please help me.
Thanks
I am not sure but instead of using
[self.navigationController popToRootViewControllerAnimated:YES];
try using,
[self.navigationController popViewControllerAnimated:YES];
And to stop swipe gesture you can use code like,
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.revealViewController.panGestureRecognizer.enabled = NO;
}
You need to reset the top view controller if you want to perform these kind of actions off of a click. E.g.
get an instance of the ECSlidingViewController
ECSlidingViewController *slidingController = self.slidingViewController;
get the view controller you wish to be on the top
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier:#"mainViewController"];
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:vc];
set the topViewController property
slidingController.topViewController = nc;
[slidingController resetTopViewAnimated:NO];

presentViewController not working as I'd like

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

not able to move to another view controller

I'm trying to move from 1st view controller -> 2nd view controller. However, it seems nothing is happening.
It is mainly from a sign-in page, so I don't need to get back to that page once I have a successful login. I'm trying right now from a button just to check.
I have 2 classes.
signInPage
optionsScreen
I need to go from 1 > 2
Inside signInPage.m
#import "optionsScreen.h"
- (IBAction)moveToNext:(id)sender {
optionsScreen *aSecondPageController =
[[optionsScreen alloc]
initWithNibName:#"optionsScreen"
bundle:nil];
[self.navigationController pushViewController:aSecondPageController animated:YES];
// [aSecondPageController release];
}
Screenshot of story board
https://drive.google.com/file/d/0B1y7ao4cGAYKaU0yRlVxcVg2bzA/edit?usp=sharing
Solution:
- (IBAction)moveToNext:(id)sender {
NSString * storyboardName = #"Main_iPhone";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:#"optionsScreen"];
[self presentViewController:vc animated:YES completion:nil];
}
In storyboard add navigation view controller. As root view controller - perhaps by default it is table view controller, so remove it - set up 1st view controller. Adding navigation controller you can push to navigation stack as many view controllers as you want.
I think what you're trying to do is present the view controller modally, not push it onto the stack (which doesn't exist). Instead you should just do this. This will not show a back button by default so you'll have to add one manually:
optionsScreen *aSecondPageController = [[optionsScreen alloc] initWithNibName:#"optionsScreen" bundle:nil];
[self presentViewController:aSecondPageController animated:YES completion:nil];
To go back, in your optionsScreen view controller, you'll need some sort of back button right? So you can do this in your viewDidLoad:
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStyleBordered target:self action:#selector(backPressed:);
Then you'll have to create a new method called backPressed:
-(void)backPressed:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}
Edit: it turns out you were trying to do what I explained above. I will leave the navigation controller bit for future reference.
If you are trying to use a navigation controller to push your options, which will give you a back button by default, then first, in your storyboard, click your sign in view controller, then at the menu bar at the top go to Editor > Embed In... > Navigation Controller. Then in your view controller switch method, you can do what you were trying before
optionsScreen *aSecondPageController = [[optionsScreen alloc] initWithNibName:#"optionsScreen" bundle:nil];
[self.navigationController pushViewController:aSecondPageController animated:YES];

Resources