How to dismiss view controller if it presented from app delegate? - ios

So I'm trying to figure out deeplinking. I have successfully gotten my app to recognize and run code I want it to depending on the path in the URL. Now when I present a View, it shows but can't get the back button or any way to dismiss it to work. Here's the code in my appdelegate:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
BuyPremiumViewController *premiumViewController = [storyboard instantiateViewControllerWithIdentifier:#"BuyPremium"];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:premiumViewController];
[self.window makeKeyAndVisible];
[self.window.rootViewController presentViewController:navigationController animated:YES completion:NULL];
The reason I use a UINavigationController is to have the nav title and back button show in the presented view. Thing is, it is not working. Here is the code that runs when the back button is tapped in the presented view:
- (void)backButton {
NSLog(#"this ran"); //check if actually ran
[self.navigationController popToRootViewControllerAnimated:YES];
}
Being at it for a hours now, help?

Try to use this code:
- (void)backButton
{
NSLog(#"this ran"); //check if actually ran
[self.navigationController dismissViewControllerAnimated:YES completion:nil];
}

Related

Showing view controller from AppDelegate when notification arrived

I am tring to show UIViewController which is inside the UIStoryboard. There isn't any problem about poping up the view. But the navigation is not working in the popup viewcontroller; such as when I touch back button
[self.navigationController popViewControllerAnimated:YES];
I am using that code in AppDelegate --> didReceiveRemoteNotification method
UIStoryboard *mystoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
PFProfileInfoVC *viewcontroller = [mystoryboard instantiateViewControllerWithIdentifier:#"SBID_ProfileVC"];
viewcontroller.strAuthorID = [userInfo objectForKey:#"aps"][#"targetId"];
[self.window.rootViewController presentViewController:viewcontroller animated:YES completion:nil];
Thanks,
When you use presentViewController, the viewController is not pushed onto the navigation stack. Normally, it is presented modally. So if you want to dismiss it, use
[self dismissViewControllerAnimated:true completion:nil];

Dismissing (or popping) a NavigationController I added manually does not work

In my AppDelegate I have the following code which is executed after receiving a notification:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UINavigationController *navigationController = (UINavigationController *)[storyboard instantiateViewControllerWithIdentifier:#"VideoPlayback"];
VideoPlaybackViewController *videoPlaybackViewController = (VideoPlaybackViewController *)[navigationController topViewController];
videoPlaybackViewController.publishing = YES;
[(UINavigationController*)self.window.rootViewController pushViewController:navigationController animated:NO];
That successfully brings up the new ViewController and apparently adds it to the navigation stack, since I can use the back button on the navigation bar to go back and subsequently dismiss the view controller.
The problem is, I don't want to use the navigation bar. In fact, I would like to hide the back button. Unfortunately, when I try to dismiss the viewcontroller using the method(s) it should use, it does nothing. I've tried using both of these to dismiss the view controller:
[self dismissViewControllerAnimated:YES completion:nil];
[self.navigationController popViewControllerAnimated:YES];
What am I doing wrong? Thanks.
You're trying to push a navigation controller into a navigation controller, which won't end well.
[(UINavigationController*)self.window.rootViewController pushViewController:navigationController animated:NO];
probably needs to be changed to:
[(UINavigationController*)self.window.rootViewController pushViewController:videoPlaybackViewController animated:NO];

Presenting Login as modal iOS?

I have an app that has a login nav controller and a tab bar controller. I have set my tab bar controller to the root controller however I want the login navigation controller to display as a modal so that I can dismiss it when they're logged in and not show it at all if they are. It is reading the right line but failing to present the landingviewcontroller. When I run the app it jumps straight to the TabBarController.
My code is as follows:
I have a method which checks if you are logged in in my app delegate which is where I am telling it to present the landing view controller (login). I know from stepping through that it is correctly determining that I'm not logged in and going to this line of code on running:
[self.window.rootViewController presentViewController:landingVC animated:YES completion:nil];
The full app delegate:
#import "GFAppDelegate.h"
#import "GFCredentialStore.h"
#implementation GFAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:[NSBundle mainBundle]];
UIViewController *tabBarController = [storyboard instantiateInitialViewController];
UIViewController *landingVC = [storyboard instantiateViewControllerWithIdentifier:#"LandingViewController"];
GFCredentialStore *store = [[GFCredentialStore alloc] init];
if (store.isLoggedIn) {
self.window.rootViewController = tabBarController;
} else {
[self.window.rootViewController presentViewController:landingVC animated:YES completion:nil];
}
// Set root view controller and make windows visible
[self.window makeKeyAndVisible];
return YES;
}
I've tried to make this clear, but understand it's probably confusing as poorly written. Thanks for any help.
What you need to do is to always set rootViewController to tabBarController, but if user is not logged call presentViewController from it. Something like it:
self.window.rootViewController = tabBarController;
[self.window makeKeyAndVisible];
if (!store.isLoggedIn) {
[tabBarController presentViewController:landingVC animated:YES completion:nil];
}
Try this:
self.window.rootViewController = tabBarController;
[self.window makeKeyAndVisible];
if (store.isLoggedIn==false) {
[tabBarController presentViewController:landingVC animated:YES completion:nil];
}
Your problem is that when tries to present view controller from self.window.rootViewController is does not exist so rootViewController == nil.
I suggest you to not present it as modal (since you don't have controller to present from), but to set login view controller as root.
self.window.rootViewController = landingVC;
But if your intent was to present login above tab bar see answers suggested before mine.

Removing ViewController after showing modally a second ViewController

Guys in my app I have some code in the app delegate method application:didFinishLaunchingWithOptions: that determines if the initial View Controller should be the LoginViewController or the MainViewController.
If the LoginViewController is showed first and the user logs in successfully I show the MainViewController modally with this piece of code:
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
FSMainViewController *vc = (MainViewController *)[storyBoard instantiateViewControllerWithIdentifier:#"MainViewController"];
vc.loginViewController = self;
[self presentViewController:vc animated:YES completion:nil];
What I want to do next, after the MainController is showed on the screen, is remove the LoginViewController from memory so in the viewWillApper:animated: method of the MainViewController I use this code to remove (or at least try to) the LoginViewController:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if (self.loginViewController) {
[self.loginViewController dismissViewControllerAnimated:NO completion:nil];
}
}
Problem is that this code leads to strange behaviors like the MainViewController being removed from the screen and this error message showing up in the console.
Unbalanced calls to begin/end appearance transitions for <LoginViewController: 0xb06e350>
I also tried calling [self dismissViewControllerAnimated:NO completion:nil] in the completion block of the presentViewController:animated:completion method but still no luck, it didn't work.
What am I doing wrong? How can I remove from memory the underlying LoginViewController when the MainViewController is presented modally?
Don't present your main view controller if you want the login controller to go away, just make it the window's root view controller.
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
FSMainViewController *vc = (MainViewController *)[storyBoard instantiateViewControllerWithIdentifier:#"MainViewController"];
Self.window.rootViewController = VC;
You can't dismissViewController after presenting another one on it or its presentingViewController. At here, you should dismiss LoginViewController first, then present MainViewController.
Otherwise, if you'd like pushViewController, you can call [self.navigationController setViewControllers: animated:] to remove LoginViewController.
If you think presentingViewController is just what you want, try something like this in application:didFinishLaunchingWithOptions:
if (self.loginViewController) { //Define loginViewController in appDelegate.h
[self dismissViewControllerAnimated:NO completion:^{
[self presentViewController:mainViewController animated:YES completion:nil];
}];
}
else{
[self presentViewController:mainViewController animated:YES completion:nil];
}

iOS switch back to background UIViewController

I'm looking for a way to present a modal view over my current UIViewController to basically show a UIActivityIndicator and force users to wait while data is being loaded.
in BaseViewController.m (base class of all my UIViewControllers):
// show loading view
-(void) showLoading
{
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
LoadingViewController *loading = [storyBoard instantiateViewControllerWithIdentifier:#"loadingView"];
loading.view.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:0.7];
self.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentViewController:loading animated:NO completion:nil];
}
This works great, but how can I go back to the background view after the loading view should be done?
Need a stopLoading method to go back to the original view:
// stop loading
-(void) stopLoading
{
// code here
}
If I try to present a new view after I present the loading view like so:
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
UIViewController *view = [storyBoard instantiateViewControllerWithIdentifier:#"loadingView"];
[self presentViewController:view animated:YES completion:nil];
The debugger gives Warning:
Attempt to present PropertyPickerViewController: 0x8af6010 on ViewController: 0x8ab23c0 which is already presenting LoadingViewController: 0x8acf530.
Try:
[self dismissViewControllerAnimated:YES completion:nil];
In fact, I'm not sure that it'a great idea to present new controller with animated gif.
The best option is (imo) show UIActivityIndicator + place a view on top on all other views to prevent user from clicking anything.
You must [self dismissViewControllerAnimated:YES completion:nil] first.
Check the Apple Documentation.

Resources