BigMountainStudio.com
BigMountainStudio.com

Reputation: 17670

How do you show a screen from anywhere in your iOS app?

Situation

An iOS app built in Xamarin with 4 screens. When you start the app it attempts to retrieve information to populate the first screen. If user token expired an exception is thrown. The AppDelegate listens for these messages and when received will show the login screen:

_window.RootViewController.PresentViewController(_loginViewController, true, null);

(_window is the first screen. _loginViewController is the screen the user enters their username and password.)

This works OK when on the first screen. But I need a way to show _loginViewController from ANY screen.

Problem/Questions

Note: My project is in Xamarin and supports iOS 8+ but I'm sure if I got a Swift solution I could work with that as well.

Upvotes: 1

Views: 539

Answers (3)

matthewrdev
matthewrdev

Reputation: 12190

You can find the top-most view controller through the following code defined as a static property on your AppDelegate:

[Register("AppDelegate")]
public partial class AppDelegate : UIApplicationDelegate
{

    public static UIViewController TopViewController
    {
        get
        {
            return TopViewControllerWithRootViewController(UIApplication.SharedApplication.KeyWindow.RootViewController);
        }
    }

    public static UIViewController TopViewControllerWithRootViewController(UIViewController rootViewController)
    {
        if (rootViewController is UITabBarController)
        {
            var tabBarController = rootViewController as UITabBarController;
            return TopViewControllerWithRootViewController(tabBarController.SelectedViewController);

        }
        if (rootViewController is UINavigationController)
        {
            var navBarController = rootViewController as UINavigationController;
            return TopViewControllerWithRootViewController(navBarController.VisibleViewController);
        }

        var presentedViewController = rootViewController.PresentedViewController;

        if (presentedViewController != null)
        {
            return TopViewControllerWithRootViewController(presentedViewController);
        }

        return rootViewController;

This is a C# port of this answer.

To present a view controller from anywhere in you app, use the above code like so:

MFMailComposeViewController mailController = new MFMailComposeViewController();

// ...

AppDelegate.TopViewController.PresentViewController(mailController, true, null);

Upvotes: 1

Iain Smith
Iain Smith

Reputation: 9703

You could create a method in the AppDelegate like so:

public void ShowLoginView()
{
    _window.RootViewController.PresentViewController(_loginViewController,true,null);
}

Then Call it from any ViewController like so:

var appDelegate = (AppDelegate)UIApplication.SharedApplication.Delegate;
appDelegate.ShowLoginView ();

And Dismiss it in the LoginViewController with this:

DismissModalViewController (true);

This will allow you to keep your navigation stack if you are using one.

Upvotes: 0

Giorgi
Giorgi

Reputation: 30883

You can use the following code to show login screen from AppDelegate regardless of the current window:

var loginViewController = UIStoryboard.FromName("MainStoryboard", NSBundle.MainBundle).InstantiateViewController("LoginPageViewController") as LoginPageViewController;
Window.RootViewController = loginViewController;

Upvotes: 1

Related Questions