In my Application I have creted view controllers for Tab Bar using XIB. I mean I added view controllers in tab bar using XIB. See picture,
So my application is like this. I have a log out functionality that will show login page. From Login page I have displayyed tab bar as
[self.view addSubview tabBarController.view];
When I log out I simply remove this tab bar and show login screen as
[self.tabBarController.view removeFromSuperView];
Then It will show login screen. When I login again, The view controllers inside tab bar is not reset.
I mean If I have showed some data like names in table view, It will be there as it is when I logged in again (some time I login as different user and I get details for previous user.). I tried
self.tabBarController.viewControllers = nil;
to reset all view controllers, but it not works any more. I think each time When I log in all view controllers should call ViewDidLoad:, currently it is calling viewWillAppear:. So please let me know how could I resolve this issue
I think since you are not using a fresh object once you sign out and sign in again, it is showing you with the last stage. Try initializing your controller object after you have logged in may work for you.
Let me know if you find any problem further.
Cheers
Tarun
All it's troubles because you use Interface Builder. Ok, try to explain. In your class like MyViewController.m ypu need set property like this:
#interface MyViewController : UIViewController
{
IBOutlet UITabBarController *mytabbar;
}
In IB (Interface Builder) you need set mytabbar property name for your UITabBarController. After that you can rectreate this variable, because you have pointer to this variable.
Related
In my app I would like to show a login screen - which will be displayed when the app starts and when the app becomes active. For reference, I am using storyboards, ARC and it is a tabbed bar application.
I therefore need to do the process in the applicationDidBecomeActive method:
- (void)applicationDidBecomeActive:(UIApplication *)application
{
if ( ... ) { // if the user needs to login
PasswordViewController *passwordView = [[PasswordViewController alloc] init];
UIViewController *myView = self.window.rootViewController;
[myView presentModalViewController:passwordView animated:NO];
}
}
To an extent this does work - I can call a method in viewDidAppear which shows an alert view to allow the user to log in. However, this is undesirable and I would like to have a login text box and other ui elements. If I do not call my login method, nothing happens and the screen stays black, even though I have put a label and other elements on the view.
Does anyone know a way to resolve this? My passcode view is embedded in a Navigation Controller, but is detached from the main storyboard.
A variety of answers finally led me to an answer which doesn't seem too complicated so I will post it here - and it actually looks really good if I am honest.
Firstly, my password view is embedded in a Navigation Controller (Editor -> Embed In) and this is connected to the main tab bar controller using a modal segue with an id, in my case 'loginModal'.
In the applicationDidBecomeActive method put something like this:
[self performSelector:#selector(requestPasscode) withObject:nil afterDelay:0.2f];
And then put this function somewhere in the App Delegate
-(void)requestPasscode{
if ( /* If the user needs to login */ ) {
[self.window.rootViewController performSegueWithIdentifier:#"loginModal" sender:self];
}
}
This will present your login view whenever the app begins or enters the foreground (for example, when switching apps).
NOTE: The above line will not work if the root of your app is embedded in a navigation controller.
There are however two bugs;
If the user was previously viewing a modal view when they dismissed the app
If the user dismissed the app on the password view.
Both of these cause the app to crash so the following line goes in the applicationWillResignActive method.
[self.window.rootViewController dismissViewControllerAnimated:NO completion:nil];
It basically dismisses all modal views that are presented. This may not be ideal, but modal views are more often then not, used for data entry and so in many cases, this is a desired effect.
You should init PasswordViewController viewcontroller from xib or if you store UI in Storyboard you should use Segue for present this controller.
I can't say about another parts but that part seems to me very weird.
My passcode view is embedded in a Navigation Controller, but is detached from the main storyboard.
in storyboards you can store view controllers and view inside of view controllers so it's not good to store some view outside of viewcontroller because you will not be able to load this view from storyboard after receiving memory warning. Please correct me if I didn't get what do you mean.
If we are going by your way there is no difference load PasswordViewController at applicationDidBecomeActive or at your first view controller at Storyboards because you calling present view controller from first loaded view controller. So you can do it in your first view controller. Also you can store some hidden view inside of your first viewcontroller and show this view if the user needs to login.
I tested it. So at first your controller become loaded and then you got method applicationDidBecomeActive. So it's better to put your code inside -(void)viewDidAppear:animated method of your first viewcontroller.
Best regards,
Danil
I want make a typical tabbar based application.
And I want to insert login view on startup before main tabbar is shown.
I tried to insert TabbarController in main view, but cannot find appropriate code. All sample code I found is insert TabbarController on startup. (in Delegate file)
My fellow suggest create toolbar on startup but hide it at login view, but I am not sure if this is a general method or not.
In this case, what is a 'recommanded' handling method of TabbarController ?
A simple solution would be to
1-Add the tab bar to UIWindow in the appDelegate as is suggested by apple.
2-then add a UINavigationController in tabbar using tabbarController.viewControllers=[NSArray arrayWithObject:yourNavController];
3- Now after alloc init on your login controller write this code before pushing it to the navigation controller of the tabbar
yourLoginController.hidesBottomBarWhenPushed=true;
4- push yourloginViewController to the navigation controller of the tabbar.
5- After authentication before pushing your MainviewController instance on the navigation set it like this
MainviewController .hidesBottomBarWhenPushed=false;
I hope these five simple steps will do the magic for you cheers :)
Please let me know if it helps you.Thanks
The approach I use for login screens which works great is:
prepare and show the regular main screen (tab bar controller with whatever initial VC you want to use)
immediately present the login screen modally (without animation) from the tab bar controller (which will obscure the tab bar controller, which is what you want)
make the login screen the startup image
Is there a way to set the view controller on the tab bar controller programmatically? Lets say I want it to show the second's tab view controller programmatically, is there a way to do that?
This is useful if I logout from my app, which is done from my third tab, when the user logins it should start from the 1st tab again. When I logout I am just showing a present modal view controller on top of what the previous view is, so I somehow needs to reset it again to the first tab bar without re-initializing it all over again.
The issue is now how do I do this?
From Apple's documentation it looks to me like you could just call the following two functions:
[myTabBarController setSelectedIndex:0];
[myTabBarController setSelectedViewController:[myTabBarController.viewControllers objectAtIndex:0]];
Hi ye you can do this
You might have tabbarcontroller object in appDelegate.
So on logout button
make object on your appDelegateClass and do this:-
appDelegate.tabBarController.selectedIndex=0;
Have a look at the reference on UITabBarController. Work with selectedIndex and selectedViewController.
I'm writing an iPhone app that is based on a UINavigationController. I'm pulling data from a server that sometime returns bogus links. I open each link by pushing a webview viewcontroller. I want to be able to include some error handling. I know if the link is no good. So I want to be able to pop the webview view controller as soon as I know that my webview has encountered an error.
Currently, I've tried using the following code:
[self.navigationController popViewControllerAnimated:YES];
I then get a Navigation bar with nothing displayed in it, but if I click where the "back" button should be it operates appropriately. The title pops up when I click where the "back" button should be. The view where the viewcontrollers usually display there content is blank white too even though I'm popping back to a UITableViewController.
I've tried this as a workaround:
UINavigationController *nav = self.navigationController;
[self.navigationController popViewControllerAnimated:YES];
[nav.visibleViewController.view setNeedsDisplay];
I've checked the viewControllers array in the UINavigationController and it has the right viewcontrollers in it (ie it has removed the viewcontroller for the webview).
I also tried putting code in the viewWillAppear of the viewcontroller I'm popping back to, but the method is never getting called.
I'm looking for a way to force the UINavigationController to reload the same way that you can call reloadData on a UITableView.
Any help would be greatly appreciated.
I saw something like this on my app where I was using a navigation bar I added in Interface Builder on the root view of a navigation controller and then programmatically creating the nav bar and its subviews for the second view. When I would pop the second view to return to the first view I would hide the self.navigationcontroller bar which would show the white space underneath until the IB nav bar of the previous view appeared. To fix this I decided to stick with programmatically creating all my navbars which fixed the issue for me.
TL;DR - if you are using both IB and programmatically made navbars this can happen when popping views, stick with one or the other for all the navbars yo
hi friends i am using UIButton for "LOGOUT" in a tabBarController having Five tabs like(Tab1,Tab2...) in IB OUTLET
i have logout page in "Tab5", when i clicks logout
i am removing page from super view and Showing "login PageView Controller",but when i log in again
it going to Same log out page...but i need to do two things like
1)Initialize Tabbar again and
2)i want to show Tabbar from first tab, like Tab1
can help anyone...
Thx in Advance
I think the question is, how do you write code to "log out" your app and clear all of the data in all of the views across a tab bar controller?
If I can help translate, I think the scenario is essentially this:
He has an app with two view controllers in MainWindow.xib, a UIViewController and a UITabBarController. Both are hooked up to IBOutlet properties on his app delegate. When the app loads, the app delegate instantiates both controllers automatically, and he shows the UIViewController with a login form.
When the user logs in, it uses some technique to hide the UIViewController and show the UITabBarController.
On a view in one of the tabs in the UITabBarController, there is a logout button. When the button is tapped, it removes the UITabBarController from the superview and shows the login UIViewController.
When the user logs in again, the UITabBarController has remained in memory, so the state has not changed since logging out. All of the data on all of the tab views needs to be reset.
What's the best practice to scrap the UITabBarController and reinstantiate it?
You can't use the following, since MainWindow.xib contains your app delegate, and another UIViewController, not just your UITabBarController:
tabBarController = [[UITabBarController alloc] initWithNibName:"MainWindow" bundle:nil];