1
votes

I followed parse.com tutorials on how to implement login + register + segue to main controller if registration or login is successful. This works beautiful.

I then wanted to implement a side navigation using SWRevealViewController. I followed APPCODA link on this and got it working only when "SWRevealViewController" is the initial view controller.

When i have my parse login controller as initial i can't see anything from the navigational controller aka "SWRevealViewController."

how would i be able fix this, make my login/register controllers the initial controllers and still be able to have SWRevealViewController when login/register is successful?

i would appreciate any help or pointers.

below is my APPDelegate.m

#import "AppDelegate.h"
#import <Parse/Parse.h>
#import <GoogleMaps/GoogleMaps.h>

@interface AppDelegate ()

@end

@implementation AppDelegate



- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

LoginView *lv = [[LoginView alloc]init];

SidebarViewController *sbvc = [[SidebarViewController alloc]init];
UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:lv];
UINavigationController *menuVC = [[UINavigationController alloc]initWithRootViewController:sbvc];

SWRevealViewController *revealController = [[SWRevealViewController alloc]initWithRearViewController:menuVC frontViewController:nav];
revealController.delegate = self;

self.menu = revealController;
self.window.rootViewController = self.menu;


[GMSServices provideAPIKey:@"XXXXXXXXXX"];

[Parse setApplicationId:@"XXXXXXXXXXXXX"
              clientKey:@"XXXXXXXXXXXXX"];

[PFAnalytics trackAppOpenedWithLaunchOptions:launchOptions];



  return YES;
    }
5
When I have to do something similar to this in my app (basically, replacing the entire navigation stack one signup/login is finished), I start with a UINavigationController and (when signup/login is finished), I push to my root UIViewController and (in that controller's viewDidAppear:) then replace the viewControllers stack for the UINavigationController without animation. If that sounds like what you're looking for, I can post my code as an answer. - mbm29414
Let me take a look and see how i can implement in mine. Thank you! - Miguel

5 Answers

3
votes

In apps with user sessions, it is usually best to keep login/signup on a separate view hierarchy from the rest of the app and present the internal structure if there is an active session. You can achieve this by checking for

[PFUser currentUser]

as it will return nil if the user is not logged in.

Provide a check in your AppDelegate like so:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    // .. Rest of your initialization code

    if ([PFUser currentUser]) {

        // Let's pop them right to the home screen
        [self showHomeScreen];
    }
    else {

        // Present login vc
        LoginView *lv = [[LoginView alloc] init];
        UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:lv];
        self.window.rootViewController = nav;
    }
    return YES;
}

- (void)showHomeScreen {

    SidebarViewController *sbvc = [[SidebarViewController alloc] init];
    UINavigationController *menuVC = [[UINavigationController alloc] initWithRootViewController:sbvc];

    UIViewController *home = [[UIViewController alloc] init];
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:home];

    SWRevealViewController *revealController = [[SWRevealViewController alloc] initWithRearViewController:menuVC frontViewController:nav];

    self.window.rootViewController = revealController;
}

Then, by including

- (void)showHomeScreen;

in AppDelegate.h, you can call this method upon successful registration/login:

AppDelegate *delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[delegate showHomeScreen];
2
votes

i just find out how to display my dashboard view from app delegate programmatically. Using SWRevealViewController & swift 2.0:

on your main.storyboard, you will have to identify the menu views (I meant not the navigation controllers)

for my right hand side menu, identity inspector->identiy->storyboardID = 'right2'.

for my left hand side menu, called it 'rear2'.

for my front view, on the navigation View controller that presents my dashboard view, i set the identity to 'dashboard'

In your appdelegate, under my function 'didFinishLaunchingWithOptions':

//this is your main.storyboard
let storyboard = UIStoryboard(name: "Main", bundle: nil)

//initialize your FRONT view controller, ie my dashboard view, mine   is a UINavigationController, which then presents a table view , ie why i instantiate with a UINavigationController.

let frontviewcontroller = storyboard.instantiateViewControllerWithIdentifier("dashboard") as? UINavigationController


//initialize REAR View Controller- it is the LEFT hand menu. 

let rearViewController = storyboard.instantiateViewControllerWithIdentifier("rear2") as? UITableViewController

//initialize RIGHT View Controller - it is your RIGHT hand menu.

let rightViewController = storyboard.instantiateViewControllerWithIdentifier("right2") as? UITableViewController

let mainRevealController = SWRevealViewController()

mainRevealController.frontViewController = frontviewcontroller
mainRevealController.rightViewController = rightViewController
mainRevealController.rearViewController = rearViewController

self.window!.rootViewController = mainRevealController
self.window?.makeKeyAndVisible()

hope it helps someone else. Thank you D.

0
votes

OK, SO i figured it out. here it goes;

Instead of creating a segue to the main view controller, create it to the SWRevealViewController. I figured that SW has that controller set as "sw_front." This will only work if you have it as a segue through the PFUser.

0
votes

Here's how I swap out my navigation hierarchy after a user logins in:

UINavigationController Version

+ (void)postSignInUICodeFromViewController:(UIViewController *)vc {
    // Log in was successful

    // Create new view controller
    ViewController1 *v1             = [[ViewController1 alloc] init];

    typeof(vc) weakVc               = vc;
    // This is a property that I have added to my
    // custom UIViewController subclass. As you might
    // guess, it's called in "viewDidAppear:"
    v1.viewDidAppearCompletionBlock = ^{
        // After pushing the new UI hierarchy into view,
        // this will delete/remove the rest of the UI stack
        weakVc.navigationController.viewControllers = @[v1];
    };
    // At this point (since the block above hasn't yet fired),
    // you're pushing your new UI hierarchy ON TOP OF the login
    // view controller
    [vc.navigationController pushViewController:v1 animated:YES];
}

UITabBarController Version

+ (void)postSignInUICodeFromViewController:(UIViewController *)vc {
    // Log in was successful

    // Create new UI hierarchy
    ViewController1 *v1             = [[ViewController1 alloc] init];
    NavViewController *nav1         = [[UINavController alloc] initWithRootViewController:v1];
    ViewController1 *v2             = [[ViewController2 alloc] init];
    NavViewController *nav2         = [[UINavController alloc] initWithRootViewController:v2];
    ViewController1 *v3             = [[ViewController3 alloc] init];
    NavViewController *nav3         = [[UINavController alloc] initWithRootViewController:v3];
    ViewController1 *v4             = [[ViewController4 alloc] init];
    NavViewController *nav4         = [[UINavController alloc] initWithRootViewController:v4];

    TabBarViewController *tabBar    = [[TabBarViewController alloc] init];
    tabBar.viewControllers          = @[nav1, nav2, nav3, nav4];

    typeof(vc) weakVc               = vc;
    typeof(tabBar) weakTabBar       = tabBar;
    __weak NavViewController *navVc = (NavViewController *)weakVc.navigationController;
    // This is a property that I have added to my
    // custom UITabBarController subclass. As you might
    // guess, it's called in "viewDidAppear:"
    tabBar.viewDidAppearCompletionBlock = ^{
        // After pushing the new UI hierarchy into view,
        // this will delete/remove the rest of the UI stack
        weakVc.navigationController.viewControllers = @[weakTabBar];
    };
    // At this point (since the block above hasn't yet fired),
    // you're pushing your new UI hierarchy ON TOP OF the login
    // view controller
    [vc.navigationController pushViewController:tabBar animated:YES];
}

In both examples, I made up a new class named ViewController1. In the UITabBarController example, all the rest are also made up class names for purposes of illustration only. You would need to put in your class names instead.

0
votes

In your login ViewController create button Action.

You can set like this.

  @IBAction func btnLoginAction(_ sender: UIButton) {

    let objAppDelegate = UIApplication.shared.delegate as! AppDelegate
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let rearViewController = storyboard.instantiateViewController(withIdentifier: "backTableVc") as? backTableVc
    let frontViewController = storyboard.instantiateViewController(withIdentifier: "ViewController") as? ViewController
    let naviRoot = UINavigationController(rootViewController: frontViewController!)
    naviRoot.navigationBar.isHidden = true
    let mainRevealController = SWRevealViewController()
    mainRevealController.frontViewController = naviRoot
    mainRevealController.rearViewController = rearViewController

    UIView.transition(from: (objAppDelegate.window?.rootViewController!.view)!, to: mainRevealController.view, duration: 0.6, options: [.transitionCrossDissolve], completion: {
        _ in
        objAppDelegate.window?.rootViewController = mainRevealController
    })
    objAppDelegate.window?.makeKeyAndVisible()

}