iOS initial log in view before navigational Controller - ios

I have been playing around with this for a couple of days and I cannot figure this out.
-> Basically I want to implement a simple login view that has a button when clicked, goes to go to the navigation controller ( in my case is "viewController" with buttons that link to mini math games which are other views).
-> Login screen should be displayed first, than navigation controller's root view when a button is clicked on the login screen
-> I have tried to declare the navigation controller when I click the button of the login screen but that seems to not work
-> Is it safe to say that a navigation controller can only be initialized in the apple delegate?
Currently I have this in my apple delegate declaring and setting my navigational controller:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
UINavigationController *navigationViewController = [[UINavigationController alloc] initWithRootViewController:self.viewController]; // self.viewController is the main screen
self.window.rootViewController = navigationViewController; // set root to navigationViewController
[self.window makeKeyAndVisible];
return YES;
}
Any ideas will be appreciated. Thank you for your time !

Your code in the app delegate looks ok. NavigationController does not need to be declared in the AppDelegate. In your case, it is definitely ok to declare it upon login button pressed.
Try this at the login event:
UIViewController *nextVC = [[UIViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:nextVC];
[self presentViewController:navController animated:YES completion:^{
}];

What I would do would be set the loginViewController as the rootViewController of the navigation. And after check if login was done successfully, you could implement [self performSegueWithIdentifier:#"identifier"] setting the game viewController as destination. (Using Storyboard would make your life much easier). Well, that's my opinion :)

Related

Switch between different Views with a Navigation Controller

I'm totally new to iOS programming. I only programmed on Android so far and Objective-C is a total different and new language for me now.
What I want to do is to not use a design that I've created with the storyboard. I want to do all programmatically, since I think it will be more dynamic if I do it like this.
The problem I'm encountering is, that I want to have 3 different views. I googled a bit, and stumbled upon some stackoverflow questions. There, people suggested using a NavigationController. Okay. Now I'm trying to implement it. What I want to have is the following
A MainViewController that has 3 different views. The first view is a loginView. The second one is displaying data and the third is displaying detailed data dependent on the click of the second view.
Is a navigationcontroller corerct for this? The problem I'm having is where I tell the app that I want to start with the MainViewController and push the LoginView in it.
I have a MainViewController.h and MainViewController.m that are subclasses of UIViewController
Now, where exactly do I do this? I have the didFinishLaunchingWithOptions method right here with the following content
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
UIViewController *viewController = [[MainViewController alloc]init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];
[navigationController pushViewController:viewController animated:NO];
self.window.rootViewController = navigationController;
[self.window makeKeyAndVisible];
return YES;
}
But that just crashes the app. What am I doing wrong? How do I get those three views? Am I starting completely wrong? Please help. As I said I'm new to iOS development. It's easy for me to programm on one view. I did that already, but I want thre different views! Thanks!
A MainViewController that has 3 different views. The first view is a loginView. The second one is displaying data and the third is displaying detailed data dependent on the click of the second view.
That's wrong.
You need three different view controllers, each of those will manage its own view.
Then you push one after another in the navigation controller, depending on user interaction.
Yes, Gonzalo Aune is rite, You should not push the rootviewcontroller in NavicationController.
Also , I will Suggest you to keep your first view (Login View) out of Navigation controller.
You can start with your MainViewController and based on check and conditions you can present LoginView on MainViewController using
[self presentViewController:loginViewController animated:YES completion:NULL];
And after successful login you can dismiss LoginViewController.
Remove this:
[navigationController pushViewController:viewController animated:NO];
You shouldnt push the ViewController since you told the NavigationController already that the ViewController would be the root one:
UINavigationController *navigationController = [[UINavigationController alloc]
initWithRootViewController:viewController];
use this code and if application is universion then use same code else remove the condition of ([[UIDevice currentDevice] userInterfaceIdiom]
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UINavigationController *navController;
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController_iPhone" bundle:nil];
{
if(result.length>0)
{
for(var i in result)
{
var ObjResult=result[i];
var content = "<div data-role='collapsible' id='set" + i + "'>";
content+="<h3>"+ObjResult.title+"<br>";
var intDate=parseInt(ObjResult['ordered date']);
content +=timestampToDate(intDate)+"</h3>"
if(isNaN(ObjResult.med_placeorderfor))
content+="<p><a>Medicle Place order for: </a>"+result[i].med_placeorderfor+"</p>";
if(isNaN(ObjResult.pres_placeorderfor)>0)
content+="<p><a>Medicle Place order for: </a>"+result[i].placeorderfor+"</p>";
if(ObjResult['order status'].length>0)
content+="<p><a>Order status: </a>"+ObjResult['order status']+"</p>";
if(ObjResult.comments.length>0)
content+="<p><a>Comments: </a>"+ObjResult.comments+"</p>";
content+="</div>";
}
$("#id_notification_list_dashboard").append( content ).collapsibleset('refresh');
$("#id_notification_list_dashboard").trigger('create');
}
else
{
$("#id_notification_list_dashboard").append("<div style=\"text-align:center\" data-role='list-divider'><h1>No data found</h1></div>").collapsibleset('refresh');
}
$('body').removeClass('ui-loading');
loadingWithMsg("hide");
}
} else {
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController_iPad" bundle:nil];
}
navController=[[UINavigationController alloc]initWithRootViewController:self.viewController];
[navController.navigationBar setTranslucent:YES];
navController.navigationBar.tintColor = [UIColor colorWithRed:161.0f/255.0f green:18.0f/255.0f blue:6.0f/255.0f alpha:1];
self.window.rootViewController =navController ;
[self.window makeKeyAndVisible];
return YES;
}

How to swap the window.rootViewController without using an UINavigationController?

In the AppDelegate I set an UIViewController, let's call it VC, as the rootViewControlloer for my app:
-(BOOL) application: (UIApplication*) application didFinishLaunchingWithOptions: (NSDictionary*) launchOptions
{
self.window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
UIViewController *VC = [UIViewController alloc] init];
self.window.rootViewController = vc;
[self.window makeKeyAndVisible];
return YES;
}
Once VC is on the screen, it asks the user a couple of questions to better configure the app before the real use.
As soon as I know what the user wants I need to swap VC with an UITabBarController, let's call it TBC, with three UINavigationController anchored to it.
How can I push TBC from VC whithout putting VC inside an UINavigationController and then use it to push TBC?
I am already able to accomplish the swap using the UINavigationController.I want a direct transiction from VC to TBC, a swap of the self.window.rootViewController whitout the need to use the extra UINavigationController.
Instead of navigating through the view controllers just create a method in app delegate which would change the root controller such as
-(void)showTBC
{
self.TBC=[[UITabbarcontroller alloc]init];
[self.window setRootViewController:self.TBC];
[self.window makeKeyAndVisible];
}
and den in your VC right after the user selects the answer make an instance of app delegate
in VC such as
AppDelegate *ap=(AppDelegate *)[[UIApplication sharedApplication]delegate];
and call
[ap showTBC];
…it worked for me..give it a try...

Tabbed application won't show Login view

I have a tab bar application in Xcode 4.3 and I'm trying to insert a login screen before the tabbar is shown. The app works OK if presentModalViewController has animated:YESbut if it is without animation the view is not showing.
#synthesize window = _window;
#synthesize tabBarController = _tabBarController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
UIViewController *viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, viewController2, nil];
self.window.rootViewController = self.tabBarController;
LogInViewController *logViewController = [[LogInViewController alloc] initWithNibName:#"LogInViewController" bundle:nil];
[self.window addSubview:_tabBarController.view];
[self.tabBarController presentModalViewController:logViewController animated:YES];
//This wont work
//[self.tabBarController presentModalViewController:logViewController animated:NO];
[self.window makeKeyAndVisible];
return YES;
}
-(void)loginDone{
NSLog(#"back to the app delegate");
[self.tabBarController dismissModalViewControllerAnimated:YES];
}
Is this the right way to do it?
Why wont the code work with animated:NO ?
I also get this on output Unbalanced calls to begin/end appearance transitions for <UITabBarController: 0x689d350>.
First of all, move [self.window makeKeyAndVisible]; before your view controller setup.
Additionally, you should be presenting the modal view controller within the viewWillAppear: method of the view controller that will be visible first, to make sure your apps view hierarchy has been fully initialized before presenting your login screen.
Don't do this:
[self.window addSubview:_tabBarController.view];
Do this:
self.window.rootViewController = _tabBarController;
This will put the tabBarController on the screen. But that's not exactly what you want... My advise is:
1) Start by putting the logViewController has the rootViewController as I showed you above.
2) Once you got what you want (login is successful) just tell the AppDelegate to switch the rootViewController. This can be done in with delegation or notifications.
Also, as Toastor indirectly pointed out, you should start the presentViewController from the UIViewController who actually initiates it (and not from the AppDelegate).

Hiding the master view in a Split View Controller

I am new to iPad development (or iPhone for that matter :) ) and I am building an app with a Split View Controller.
The thing is the first screen should be a single screen. I want the user to write user/pass data to connect to a remote server, and there's not really anything to show in the master view.
I know I can return YES in the splitViewController:shouldHideViewController:inOrientation:, and that works fine for the first screen, but I'd like to get the two views when the user taps the login button and the credentials are validated.
I can put some condition in shouldHideViewController and that shows the two views in the second screen and only the detail in the first, but shouldHideViewController is only called if I rotate my iPad, not when I perform the segue.
Do you have any tips to do this? Should I change my UI approach to something else? Any suggestions are welcome.
starting from scratch is a good idea. You have more control over whats going on IMO.
At your starting point you want to add your LoginViewController.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.loginController = [[LoginViewController alloc] initWithNibName:#"LoginViewController" bundle:nil];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
Later when the authentication process has finished you want to continue with SplitView, right?
- (void)continueWithSplitView {
UINavigationController *leftNav = [[UINavigationController alloc] initWithRootViewController:self.masterViewController];
UINavigationController *rightNav = [[UINavigationController alloc] initWithRootViewController:self.detailViewController];
self.splitViewController.viewControllers = [NSArray arrayWithObjects:leftNav, rightNav, nil];
self.view.window.rootViewController = self.splitViewController;
}
Notice that in both methods your desired viewController is set as the rootViewController property of UIWindow. This will automatically add the view of your controller as the top level view in UIWindow.
Furthermore make sure that you are following the MVC pattern e.g. a model object for your credentials organisation.

Trying without success to add Navigation Controller to existing iOS app

I'm experimenting with OAuth 2.0. which brings up a window containing a UIWebView as a canvas for the authentication server to communicate through. Right now, it is being shown as a modal view with its own view controller, and doesn't have a back button or cancel button. So the user has no way to escape from the sign-in process.
I want to have the webView handled by a navigation controller so I can push the webView's view controller.
I am having problems with doing this. It seems to me I should be able to just create a UINavigationController object with the root view controller being the main view controller, like this
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self];
However, this line crashes the program without any error message in the debugger.
I thought I could place a line to push the web view controller immediately after the line above, like this:
[navController pushViewController:windowController animated:YES];
But, without getting past the first line, I can't begin to work out the details on getting the web view to show and then configure the back button.
UPDATE
Here is some context. This is in a single view application. The following code is in the main view controller, which brings up the sign-in dialog. I would like to replace the last line, where the presentModalViewController is called, with a push of the windowController onto a navController stack. Note the commented code at the end, where the initialization of the navigation controller is located.
- (IBAction)signInClicked:(id)sender {
if (![self isSignedIn]) {
// Sign in
[self runSigninThenInvokeSelector:#selector(updateUI)];
}
[self updateUI];
}
- (void)runSigninThenInvokeSelector:(SEL)signInDoneSel {
NSString *clientID = mClientId;
NSString *clientSecret = mClientSecret;
// Show the OAuth 2 sign-in controller
NSString *scope = [GDataServiceGoogleBlogger authorizationScope];
GTMOAuth2ViewControllerTouch *windowController;
windowController = [[GTMOAuth2ViewControllerTouch controllerWithScope:(NSString *)scope
clientID:(NSString *)clientID
clientSecret:(NSString *)clientSecret
keychainItemName:(NSString *)kKeychainItemName
delegate:(id)self
finishedSelector:#selector(windowController:finishedWithAuth:error:)] retain];
//UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:self]; // This causes a crash when it is not commented out.
[self presentModalViewController:windowController animated:YES];
}
The application delegate didFinishLaunchingWithOptions is set up this way:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
self.viewController = [[[blogSpotViewController alloc] initWithNibName:#"myNibName" bundle:nil] autorelease];
self.window.rootViewController = self.viewController;
[self.window makeKeyAndVisible];
return YES;
}
Well, you can present this as a modal controller. You just need to arrange to call dismissModalViewController: in response to a button or some other event on the 'windowController'.
But if you want to use a navigation controller, then you can set that up in application:didFinishLaunchingWithOptions: like so:
// create window here like now
blogSpotViewController *viewController = [[blogSpotViewController alloc] initWithNibName:#"myNibName" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:viewController];
[viewController release];
// TODO: hold onto this navController in a property if you really need that.
self.window.rootViewController = navController;
[navController release];
// present window here as you are now
This embeds your main view controller in a navigation controller. Then back in your runSigninThenInvokeSelector: you can...
[self.navigationController pushViewController:windowController animated:YES];
Hope that points you in the right direction.

Resources