Tabbar delegate method is not getting called after changing storyboard - ios

I have login and signup viewcontrollers in Login storyboard not in the Main storyboard.
Once signup or login is successful, then I am changing Login storyboard to Main. The following code works but when I select any tab, it does not call tab delegate method in the AppDelegate
However, if user is already succesfully signup or logged in, then it calls the following tabbar delegate method.
LoginViewController.m
if(isLoginSuccess)
{
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
CustomTabBarViewController *tbc = [mainStoryboard instantiateViewControllerWithIdentifier:#"tabbar"];
tbc.selectedIndex = 2;
[self presentViewController:tbc animated:YES completion:nil];
}
AppDeletage.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
CustomTabBarViewController *tabBarController = (CustomTabBarViewController *)self.window.rootViewController;
tabBarController.delegate = self;
return YES;
}
-(void) tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController
{
if (tabBarController.selectedIndex == 2) {
if(![self isRegistered])
{
UIStoryboard *loginStoryboard = [UIStoryboard storyboardWithName:#"LoginStoryboard" bundle:nil];
UIViewController *vc = [loginStoryboard instantiateViewControllerWithIdentifier:#"LoginViewController"];
[ROOTVIEW presentViewController:vc animated:YES completion:nil];
}
else
{
tabBarController.selectedIndex = 2;
}
}
}
Update :
AppDelegate is not getting called but I wonder why the following code does not open Loginstoryboard in the AppDelegate after user is logout.
#define ROOTVIEW [[[UIApplication sharedApplication] keyWindow] rootViewController]
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"LoginStoryboard" bundle:nil];
UIViewController *vc = [mainStoryboard instantiateViewControllerWithIdentifier:#"LoginViewController"];
[ROOTVIEW presentViewController:vc animated:YES completion:nil];

Please find below code.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UIStoryboard *main = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UITabBarController *tabController = [main instantiateViewControllerWithIdentifier:#"TabbarController"];
tabController.delegate = self;
return YES;
}
-(void) tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController{
NSLog(#"Selected Index - %lu",(unsigned long)tabBarController.selectedIndex);
}
On ViewController's Button Click Method,
- (IBAction)btnLoginTapped:(id)sender {
UIStoryboard *main = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UITabBarController *tabController = [main instantiateViewControllerWithIdentifier:#"TabbarController"];
tabController.selectedIndex = 1;
[self presentViewController:tabController animated:YES completion:nil];
}
then on Main.storyboard, Drag Object from the Object Library and put it below First Responder in Tab bar Controller Scene, Set the Object class to AppDelegate, then right click on Tab Bar Controller and set delegate to that Object Class as shown in below image.
Let me know it is working or not, I'm ready to help with the solution.

Related

React Native - show ViewController by AppDelegate method

AppDelegate.m
This works correct (show splash when app goes into the background)
- (void)applicationDidEnterBackground:(UIApplication *)application
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"NativeScreens" bundle:nil];
SplashVC *SplashViewController=[storyboard instantiateViewControllerWithIdentifier:#"SplashVC"];
[self.window.rootViewController presentViewController:SplashViewController animated:NO completion:NULL];
}
But now I need to call this from the react-native.
I created a method with the same functionality:
RCT_EXPORT_METHOD(showCustomNativeSplashScreen)
{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"NativeScreens" bundle:nil];
SplashVC *SplashViewController=[storyboard instantiateViewControllerWithIdentifier:#"SplashVC"];
[self.window.rootViewController presentViewController:SplashViewController animated:NO completion:NULL];
}
It is available in RN, (Im see it from console.log) but when I call it - nothing happens.
import { NativeModules } from 'react-native';
...
console.log(NativeModules.AppDelegate); // Object{showCustomNativeSplashScreen: function}
NativeModules.AppDelegate.showCustomNativeSplashScreen(); // nothing :(
What am I doing wrong?
It was necessary to find the upper controller source
- (UIViewController *)topViewController{
return [self topViewController:[UIApplication sharedApplication].keyWindow.rootViewController];
}
- (UIViewController *)topViewController:(UIViewController *)rootViewController
{
if (rootViewController.presentedViewController == nil) {
return rootViewController;
}
if ([rootViewController.presentedViewController isMemberOfClass:[UINavigationController class]]) {
UINavigationController *navigationController = (UINavigationController *)rootViewController.presentedViewController;
UIViewController *lastViewController = [[navigationController viewControllers] lastObject];
return [self topViewController:lastViewController];
}
UIViewController *presentedViewController = (UIViewController *)rootViewController.presentedViewController;
return [self topViewController:presentedViewController];
}
RCT_EXPORT_METHOD(showCustomNativeSplashScreen)
{
self.lastTopVC = [self topViewController];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"NativeScreens" bundle:nil];
SplashVC *SplashViewController=[storyboard instantiateViewControllerWithIdentifier:#"SplashVC"];
[self.lastTopVC presentViewController:SplashViewController animated:NO completion:NULL];
}

Different UIViewController logged in

When user open the app it show login UIViewController. When user log in it redirect to next mapkit UIViewController. But when user open app again I would like that he will skip login UIViewController. How can I do that? I tried programatically redirect in login method viewWillAppear but it works bad(It show controller for second).
A better way is to add this check in the AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if(isLoggedin) {
Storyboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *mapViewController = [storyboard instantiateViewControllerWithIdentifier:#"mapViewController" ];
self.rootViewController = [[UINavigationCotroller alloc] initWithRootViewController:mapViewController];
}
return YES;
}
Instead of checking the login in the viewWillAppear: method of the first view controller, do it in the didFinishLaunchingWithOptions: method of your application delegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if (loggedIn) {
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
[navigationController.topViewController performSegueWithIdentifier:#"1to2" sender:navigationController.topViewController];
return YES;
}
}
where 1to2 is the identifier of the segue from view controller 1 to 2.
You can do it like this:
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// replace with your real auth-checking
if ([self wasAuthorized] == NO) {
[self showLoginController];
}
return YES;
}
- (UIViewController *)mainController {
UINavigationController *rootNavigationController = (UINavigationController *)[[self window] rootViewController];
return [[rootNavigationController viewControllers] firstObject];
}
- (void)showLoginController {
UIViewController *loginController = [self loginController];
dispatch_async(dispatch_get_main_queue(), ^{
[self.mainController presentViewController:loginController animated:YES completion:nil];
});
}
- (UIViewController *)loginController {
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
return [mainStoryboard instantiateViewControllerWithIdentifier:#"LoginNavController"];
}

iOS: Present segue programmatically without loosing the navigation

I'm working in iOS app but I'm trying to present a tableview when I click a button in one of my scenes like it shows in the image bellow:
I tried this way:
- (IBAction)presentScene:(id)sender
{
NSString *storyboardName = #"Main";
NSString *viewControllerID = #"myScene";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle:nil];
MyViewController *controller = (MyViewController *)[storyboard instantiateViewControllerWithIdentifier:viewControllerID];
[self presentViewController:_categoViewController animated:YES completion:nil];
}
But doesn't show the navigation to go back to the main table view or I can't even set the title of the tableview. Any of you knows how can present tableview?
try this:
[[self navigationController] pushViewController:YOUR_DESTINATION_VIEW_CONTROLLER animated:YES];
You should present the tableViewController with UINavigationController like so:
MyViewController *controller = (MyViewController *)[storyboard instantiateViewControllerWithIdentifier:viewControllerID];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:controller];
[self presentViewController:navigationController animated:YES completion:nil];
EDIT:
You should add a UINavigationController in your storyboard like this:
If you do not want to show the navigationBar in your HomeVC then hide it:
// HomeVC.m
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.navigationController setNavigationBarHidden:NO animated:YES];
}
Finally, push the MyViewController:
- (IBAction)presentScene:(id)sender {
NSString *viewControllerID = #"myScene";
UIStoryboard *storyboard = self.storyboard;
MyViewController *controller = (MyViewController *)[storyboard instantiateViewControllerWithIdentifier:viewControllerID];
[self.navigationController pushViewController: controller animated:YES]
}
After experimenting with everything I finally found what I was looking for:
self.tabBarController.selectedIndex = 1;

How to go to UITabBarController after clicking the respective UIButton

how to go on home page on login button click
- (IBAction)loginClick:(id)sender {
HomeVC *secondView = [self.storyboard instantiateViewControllerWithIdentifier:#"home"];
[self.navigationController pushViewController:secondView animated:YES];
self.tabBarController.selectedIndex = 1;
}
First you have to set your login page as a Root controller and when you successfully logged in then you have to change your root controller and make your Tab Bar as a root controller.
Perform this code in your AppDelegate and call these method on your login and logout page.
#property (strong, nonatomic) UIWindow *window;
#property(nonatomic,readonly) UITabBar *tabBar;
#property(nonatomic,strong) UITabBarController *tabBarController;
- (void)Login{
[self.window setRootViewController:nil];
UIStoryboard *MainStoryboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle: nil];
UITabBarController *bar= (UITabBarController*)[MainStoryboard instantiateViewControllerWithIdentifier:#"tabbar"];
self.window.rootViewController=bar;
}
-(void)Logout
{
// self.window.rootViewController = nil;
UIStoryboard *mainStoryboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
UINavigationController*vc = [mainStoryboard instantiateViewControllerWithIdentifier:#"homepage"];
// Homepage *controller = [[Homepage alloc] initWithDelegate:self];
self.window.rootViewController = vc;
}
Implement didFinishLaunching method this way :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController *rootViewController = [storyboard instantiateViewControllerWithIdentifier:#"LoginView"];
BOOL isLogin = [[NSUserDefaults standardUserDefaults] boolForKey:#"IS_LOGIN"];
if (isLogin == YES)
{
rootViewController = [storyboard instantiateViewControllerWithIdentifier:#"MainHomeTabView"];
}
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
And set TRUE when you pressed login button
- (IBAction)login:(id)sender
{
[[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:#"IS_LOGIN"];
[[NSUserDefaults standardUserDefaults] synchronize];
TabListViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"MainHomeTabView"];
AppDelegate *appDelagate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelagate.window.rootViewController = vc;
}

In XCode 5 and iOS 7 push view controller in ViewDidLoad does not working

Hi I am trying to push a view controller in viewDidLoad
I am using storyboard.
In ViewDidLoad, I am checking that user is login and he is created his profile.
if user is not logged in or he does not created his profile then pushing the another view controller for login/profile view.
The following code does not working.
- (void)viewDidLoad
if(USER_IS_LOGGED_IN)
{
if(USER_PROFILE_COMPLETED)
{
[self sendRequest];
}
else
{
//push profile view
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ProfileViewController *profileViewController = (ProfileViewController *)[storyboard instantiateViewControllerWithIdentifier:#"ProfileView"];
profileViewController.isFromDealView = YES;
profileViewController.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:profileViewController animated:YES];
}
}
else
{
//push login view
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
LoginViewController *loginViewController = (LoginViewController *)[storyboard instantiateViewControllerWithIdentifier:#"LoginView"];
loginViewController.isFromDealView = YES;
loginViewController.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:loginViewController animated:YES];
}
}
why don't you create the segue from your viewController to the Login and Profile View Controller and use performSegueUsingIdentifier: and push the navigation Controller using prepareForSegue: method
- (void)viewDidLoad
{
if(USER_IS_LOGGED_IN)
{
if(USER_PROFILE_COMPLETED)
{
[self sendRequest];
}
else
{
//push profile view
[self performSegueWithIdentifier:#"profileSegue" sender:self] ;
}
}
else
{
//push login view
[self performSegueWithIdentifier:#"loginSegue" sender:self] ;
}
}
in prepareforsegue method
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"profileSegue"]) {
ProfileViewController *profileViewController = segue.destinationViewController;
profileViewController.isFromDealView = YES;
profileViewController.hidesBottomBarWhenPushed = YES;
}
else if([segue.identifier isEqualToString:#"loginSegue"]){
LoginViewController *loginViewController = segue.destinationViewController;
loginViewController.isFromDealView = YES;
loginViewController.hidesBottomBarWhenPushed = YES;
}
else{
//no segue to push
}
}
I am little confuse with your code but any way try this
- (void)viewDidLoad {
if(USER_IS_LOGGED_IN) {
if(USER_PROFILE_COMPLETED)
{
[self sendRequest];
}
else
{
//push profile view
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
ProfileViewController *profileViewController = (ProfileViewController *)[storyboard instantiateViewControllerWithIdentifier:#"ProfileView"];
profileViewController.isFromDealView = YES;
profileViewController.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:profileViewController animated:YES];
}
} else {
//push login view
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
LoginViewController *loginViewController = (LoginViewController *)[storyboard instantiateViewControllerWithIdentifier:#"LoginView"];
loginViewController.isFromDealView = YES;
loginViewController.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:loginViewController animated:YES];
}`
}

Resources