iOS 6 NavigationController not loading - ios

I have an app that I migrated over from iOS 5 to iOS 6 and am having trouble with the UINavigationController not displaying correctly.
In my app, the user must login and they are presented that login screen in a modal view after pressing a button.
WelcomeViewController.m
- (IBAction)signInButtonSelected:(id)sender
{
LoginViewController *loginViewController = [[LoginViewController alloc] initWithNibName:nil bundle:nil];
[self.navigationController presentViewController:loginViewController animated:YES completion:^{}];
}
The view loads correctly and has lets the user enter their login credentials. However, when they press the login button, the next view is presented and it SHOULD have a UINavigationBar at the top, except it doesn't. If I quit the app and restart it, the UINavigationBar shows up in that view properly. I have not a clue as to why going from the login view to the logged in screen hides the navigation controller.
Here is the code that is executed when the login button is pressed that loads the next view:
LoginViewController.m
WallViewController *wallViewController = [[WallViewController alloc] initWithNibName:nil bundle:nil];
[(UINavigationController *)self.presentingViewController pushViewController:wallViewController animated:YES];
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
If anyone can shed some light on to why this is happening that would be great!
Thanks!

Figured it out. In my App Delegate, I had placed:
navController.navigationBar.hidden = YES;
And it would hide the navigation bar after a user would login. Not exactly sure why this in the app delegate would affect a view later on down the line. But once it was removed, it works perfectly!
Thanks for the help!

Related

Having trouble in PresentDismiss & NavigateViewController push/pop

I have the whole app embedded in UINavigationController. Now there is the Home Screen that has several modules for user to choose. Now, when the user clicks on the module it is NAVIGATED and if user desires to choose some another module from any other modules available, there is a button in navigation bar, which PRESENTS the HomeViewController modally on top of the current module and then user can choose any module from there which will NOT BE PRESENTED instead they will NAVIGATE.
Now what I have done is made a delegate called navigate on HomeViewController and will be override by viewcontrollers of each module and it will take the reference of the new ViewController with it. Then when this method is called I have first dismissViewController the HomeViewController and then navigated to the new ViewController that I have the reference.
Now, what the real issue is that SOMETIMES there is a jerk when navigating from one module to other and sometime it works fine. That why I am not able to debug also. The jerk is that when a module is clicked from HomeViewController, the home screen disappears and the appears again and then it actually navigates.
The code for navigating to a module from HomeViewController is
RadiusSearchViewController *rad = [self.storyboard instantiateViewControllerWithIdentifier:#"RadiusSearchViewController"];
[self.delegate navigate:rad];
This navigation overrided method in all modules is
-(void)navigate:(UIViewController*)uiViewController{
NSLog(#"inside navigate method");
[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
[self.navigationController pushViewController:uiViewController animated:YES];
}
I assure you that it is coming in this method.
Now the code that presents the HomeViewController modally is
ViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"HomeVC"];
vc.view.backgroundColor = [[UIColor whiteColor]colorWithAlphaComponent:0];
vc.delegate = self;
vc.providesPresentationContextTransitionStyle = YES;
vc.definesPresentationContext = YES;
vc.modalPresentationStyle = UIModalPresentationOverCurrentContext;
vc.fromOutside = true;
NSLog(#"Presneting...");
[self presentViewController:vc animated:NO completion:nil];
The reason for PRESENTING and NOT NAVIGATING the HomeViewController is that it comes on the top of the current module in transparent form which is necessary.
REMEMBER: It happens sometimes not all of the time. Like you can say half of the times.
[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
[self.navigationController pushViewController:uiViewController animated:YES];
this should be changed to...
[self.presentedViewController dismissViewControllerAnimated:YES
completion:^{
[self.navigationController pushViewController:uiViewController animated:YES];
}];
this will make sure navigation view controller will be called after dismiss is done. check and see if it solves your problem.

Difficulties changing between viewControllers in xcode

I have 3 different viewControllers. first one is the main page where you will see many thumbnail of images. Second controller will only open when an image is clicked. Last ViewController is the login which opens when the user is not logged in but trying to view the second controller or clicked login from the main controller. In the login controller I have a back button to go to main page. Remember the user can access login from two different ways. by clicking on the image or clicking login in the main controller directly. So the issue is the back button does work properly. When the login page is accessed from the main controller directly, then the back button works fine it takes you to the main page. However, if you click on any of the thumbnails the second controller will try to open but since your not logged in the login page will show and when you click the back button to send you to the main controller, it won't go to main instead it will reload the same page and you kind of stock in a loop you have to login or exit the app. any ideas why?
The First ViewController Identifier is set to "mainImages".
- (IBAction)backToMain:(id)sender {
[self dismissViewControllerAnimated:NO completion:nil];
NSString * storyboardName = #"MainStoryboard";
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:storyboardName bundle: nil];
UIViewController * MI = [storyboard instantiateViewControllerWithIdentifier:#"mainImages"];
UINavigationController *navController = self.navigationController;
if (navController) {
[navController pushViewController:MI animated:NO];
}
}
I also tried this but no luck:
[self dismissViewControllerAnimated:NO completion:nil];
UIViewController * MI = [self.storyboard instantiateViewControllerWithIdentifier:#"mainImages"];
[self presentViewController:MI animated:NO completion:nil];
Try this if you are presenting as modal:
- (IBAction)backToMain:(id)sender {
[self dismissViewControllerAnimated:NO completion:^{
UIWindow *window = [[UIApplication sharedApplication].windows firstObject];
UINavigationController *nav = (UINavigationController *)window.rootViewController;
[nav popToRootViewControllerAnimated:YES];
}];
}
If you need to "go back" from the login view to any other view (in this case 2 of them), you should try using a Modal Segue, a modal segue lose the navigation controller view stack but allow you to dismiss the login view and go back to you last view.
On the first (or thumbnail images view controller) show your new modal view as this:
UIViewController *modalViewController = [[UIViewController alloc] init];
[self presentViewController:modalViewController animated:YES completion:nil];
And then, to dismiss (on login view controller):
- (IBAction)backToMain:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}

iOS : UI - Design login page and Tab view - Tab not coming after Login

I am a newbie in iOS development. I want to create 2 screens - (1) Login & on successful login (2) a Tab based view.
I started up with creating Login text boxes & button for Login in Storyboard. Now, how do I create other Tab view & show that new tab view on login btw click.
What would be the best approach for creating this type of screens ? In tutorials, I can find of creating Tabbed View as main or dynamic. Couldn't find the way I am looking for. FYI, I would like my app to be compatible with iOS 4 and above. I wish to plan and use resources accordingly. Sharing this, as in case it affects the approach to be selected.
Thanks
UPDATED AGAIN :
As shown/suggested in answer, I created a new project as TabbedView and added LoginViewController to the storyboard. In my LoginViewController under "Identity Inspector" - Identity - StoryboardID - gave name "loginViewController". Created Custom class for TabControl - MC_MainTabBarController.
My storyboard file name is Main_iPhone.storyboard.
In my AppDelagate file in didFinishLaunchingWithOptions method before return I added :
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
// MY First View of Tab
MC_ChatViewController *chatViewTab = [[MC_ChatViewController alloc] init];
// MY TabController class
MC_MainTabBarController *tabCtrler = [[MC_MainTabBarController alloc] init];
// Login view controller
LoginViewController *loginViewController = [storyboard instantiateViewControllerWithIdentifier:#"loginViewController"];
[loginViewController setModalPresentationStyle:UIModalPresentationFullScreen];
[tabCtrler presentViewController:loginViewController animated:NO completion:nil];
This should bring first Login screen and then the tabs, but it brings straight away tabs & no login screen. I feel I might be going wrong at 2 places - "Main_iPhone" OR I may have to set loginViewController as storyboard id somewhere else also. Where can't get it ?
UPDATE
Even after calling tabCtrler presentViewContorller ... also, still Login screen isn't showing up. Yet straight tabs are only visible. At Runtime, I see the following Warning :
Warning: Attempt to present <LoginViewController: 0x8ab4e80> on <MC_MainTabBarController: 0x8d4dc20> whose view is not in the window hierarchy!
UPDATE
With the below code in didFinishLaunchingWithOptions in AppDelegate I can get my login page.
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
MC_MainTabBarController *tabCtrler = [[MC_MainTabBarController alloc] init];
LoginViewController *loginViewController = [storyboard instantiateViewControllerWithIdentifier:#"loginViewController"];
[[[[UIApplication sharedApplication] delegate] window] setRootViewController:loginViewController];
Now, from Login -submitBtnClick, how do I get to my default Tab view ?? That should be handled in submitBtnClick in login class or her in AppDelegate only. How to achieve the same ?
Can please help to bring the login screen prior to tabs.
Thanks
Thanks BoranA & all friends,
I had to extend BoranA's answer for this to work, hence am sharing the solution that worked for me. AS BoranA instructed,
I created a new Project with tabbed template.
add LoginViewController screen to the Storyboard and gave it Id - "loginViewController".
Created class's for LoginViewController and MC_MainTabBarController for the main tab controller.
Added Storyboard Id to tab controller as "mainView".
In AppDelgate.h, added properties for loggedIn & tabController object
#property (nonatomic) bool isLoggedIn;
#property(nonatomic,strong)MC_MainTabBarController *tabBarController;
In AppDelegate.m :
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
// Show Login view if not logged On
if (!self.isLoggedIn) {
[self showLoginScreen:NO];
}
return YES;
}
-(void) showLoginScreen:(BOOL)animated {
// Get login screen from storyboard and present it
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
LoginViewController *loginViewController = [storyboard instantiateViewControllerWithIdentifier:#"loginViewController"];
[self.window makeKeyAndVisible];
// Show the Login Screen
[self.window.rootViewController presentViewController:loginViewController animated:animated completion:nil];
}
-(void) logout {
// Remove data from singleton (where all my app data is stored)
//[AppData clearData];
// Reset view controller (this will quickly clear all the views)
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
// Create the tabBarController using Storyboard ID
self.tabBarController = (MC_MainTabBarController *)[storyboard instantiateViewControllerWithIdentifier:#"mainView"];
// Show the Tab Bar Controller
[self.window setRootViewController:self.tabBarController];
// Show login screen
[self showLoginScreen:NO];
}
Finally, in LoginViewController.m, when I am done with all process and have to show the main view, I call the following method :
-(void) loginWasSuccessful {
// Send Notification
[[NSNotificationCenter defaultCenter] postNotificationName:#"loginSuccessful" object:self];
// Dismiss Loginscreen
[self dismissViewControllerAnimated:YES completion:nil];
}
// LOGIN BTN CLICKED
- (IBAction)loginBtnClicked:(id)sender {
// Validate & Process Login
// If user is logged successfully, then only go to the main view.
if (self.processLogin)
[self loginWasSuccessful];
}
With this code, if isLoggedIn if AppDelegate is true, then it will straight away show the Tab controller and won't show Login screen. IF isLoggedIn is false, then first Login screen will come up and on successful login only tab controller will show up.
Hope this helps someone save time and get solution to their problem.
Thanks.
Create a project with tabbed application template.
Create your LoginViewController separately in your storyboard.
Add below code to your AppDelegate's didFinishLaunchingWithOptions method.
if (!isLoggedIn)
{
LoginViewController *loginViewController = [storyboard instantiateViewControllerWithIdentifier:#"loginViewController"];
[loginViewController setModalPresentationStyle:UIModalPresentationFullScreen];
[yourTabbarController presentViewController:loginViewController animated:NO completion:nil];
}
note: Dont't forget to specify storyboard id of your view as "loginViewController".

how to solve strange behavior of ui tab bar in ios 7

I am creating an application in which I am using the tab bar with 3 tabs. Everything works fine in iOS 6, but in iOS 7 when I click on tab 3 it checks if user is logged in or not.
-(void)viewWillAppear:(BOOL)animated
{
appdelegate=(AppDelegate *)[[UIApplication sharedApplication]delegate];
appdelegate.strLoginMessage=#"setting";
BOOL isLogin= [[[NSUserDefaults standardUserDefaults] objectForKey:#"isLogin"]intValue ];
if (isLogin)
{
[self webService_Count];
}
else
{
appdelegate.showLoginBack=NO;
ViewController *view=[[ViewController alloc]initWithNibName:#"ViewController" bundle:nil];
[self.navigationController pushViewController:view animated:YES];
}
}
If user is not login then i send it to the login page. But from here if user taps on the tab 3 it go to setting page without login. And if user again clicks tab 3 it shows black screen. I can't understand why?
This is how I setup my tab bar in appDelegate
self.nav= [[UINavigationController alloc]initWithRootViewController:self.viewController];
self.nav1=[[UINavigationController alloc]initWithRootViewController:self.messageviewcontroller];
self.nav2=[[UINavigationController alloc]initWithRootViewController:self.settingviewController];
in nav1 and nav2 i check if the user login or not in view will appear.
I can only imagine viewWillAppear: is not being called on each subsequent tap of the UITabBarItem.
Have you set a breakpoint in the method to check?
If it is in fact thew viewWillAppear: method not being called, I would suggest placing this code somewhere which is called on each tap on the UITabBarItem.
following solve my problem.i changes the root view after login and assiged the login page as root view at logout time.
ViewController *view=[[ViewController alloc]initWithNibName:#"ViewController" bundle:nil];
[self.navigationController setViewControllers:[NSArray arrayWithObject:view] animated:YES];
MessageLoginViewController *message=[[MessageLoginViewController alloc]initWithNibName:#"MessageLoginViewController" bundle:nil];
[appdelegate.nav1 setViewControllers:[NSArray arrayWithObject:message]];
You should check if user is not login then show login screen as a root view instead of push it into current navigation controller:
ViewController *view = [[ViewController alloc]initWithNibName:#"ViewController" bundle:nil];
appDelegate.window.rootViewController = view;

How do I set UIButton to go to the previous screen?

I have a help screen that can be accessed from any other screen. The only button there is a "back" arrow. Right now it always goes back to the main screen. However, I need it to go back to which ever screen that was before it. I've hunted through stackoverflow and google but no luck.
EDIT
snippet of the code I'm using now:
appViewController *homeView = [[appViewController alloc] initWithNibName:nil bundle:nil];
homeView.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:homeView animated:YES];
From the modal view controller that is being presented right now, make it dismiss itself when clicking the home button:
- (void)buttonClicked
{
[self dismissModalViewControllerAnimated:YES];
}
On button click You can use.
[self.navigationController popViewControllerAnimated:YES];
Maybe this link will help you: How to navigate previous screen from camera view in iphone?
Its about navigation and how to remove the last screen.
Or use this in the click event of button.Create an instance of the view controller to be opened
EnterNameController *newEnterNameController = [[EnterNameController alloc] initWithNibName:#"EnterName" bundle:[NSBundle mainBundle]];
[[self navigationController] pushViewController:newEnterNameController animated:YES];

Resources