how to add a login screen before existing ViewController in Xcode3 - iphone

I need to add a screen to capture username and password before loading the first view of an app on an iPhone. The whole app is coded and working except for this (late) addition. This is my first app in Xcode so I am not very familiar with the system at all.
I have a LoginViewController set up, but don't know how to add it to the front of the app so that it loads first and then loads my RootViewController afterwards (I need the login details before loading the next view).
The header of my appdelegate is presently
#import <UIKit/UIKit.h>
#class RootViewController;
#interface Online_HW_DiaryAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
RootViewController *viewController;
UINavigationController *navigationController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
#property (nonatomic, retain) IBOutlet RootViewController *viewController;
#end
but I'm not sure what I need to modify - or indeed what else will need to be modified? Any advice gratefully appreciated.

I think the fastest path is this: In viewDidAppear of RootViewController, detect the login needed condition and present a new LoginVC modally.
// RootViewController.m
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if (/* user must login */) {
LoginVC *newVC = [[LoginVC alloc] initWithNibName:.....];
[self presentModalViewController:newVC animated:YES];
} else {
// your old viewwillappear logic
}
}
The LoginVC, upon determining that the user has logged in successfully, can dismiss itself.
// LoginVC.m
- (void)loginFinished {
// after some asynch call that validated the user credentials
[self dismissModalViewControllerAnimated:YES];
}

Related

Can't call controller method from delegate

I'm trying to do something like this: http://www.pushplay.net/2009/05/framework-for-having-multiple-views-in-an-iphone-app/
So far I've got this structure: appDelegate -> rootViewController -> welcomeViewController
I've a method (doSomething) in my delegate, which is called by an IBAction in welcomeViewController. It works, I can do an NSlog in doSomething and it shows the method is being called within the delegate.
The problem is when I run a command like [rootViewController loadNewView] in my doSomething method (in the delegate), it does nothing. It doesn't error, it just does nothing.
I've been reading and seen protocols and notifications are suggested, but I'd like to know why this method using the delegate doesn't work and if there is any way to fix it.
SurveyClientAppDelegate.h
#interface SurveyClientAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
RootViewController *rootViewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet RootViewController *rootViewController;
-(void)doSomething;
#end
SurveyClientAppDelegate.m
- (void)doSomething {
NSLog(#"Attempt: rootViewController loadLocationList");
[rootViewController loadLocationList];
}
RootViewController.h
#interface RootViewController : UIViewController {
WelcomeViewController *welcomeView;
}
#property (nonatomic, retain) WelcomeViewController *welcomeView;
#property (nonatomic, retain) SurveyListViewController *surveyList;
-(void)loadLocationList;
RootViewController.m
- (void)loadLocationList
{
NSLog(#"RootViewController: loadLocationList");
}
WelcomeViewController.h
#interface WelcomeViewController : UIViewController
-(IBAction)viewList:(id)sender;
-(void)loadLocationList;
WelcomeViewController.m
- (void)viewList:(id)sender
{
SurveyClientAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate doSomething];
}
Are you keeping a reference to rootViewContoller in your welcomeViewController? It's possible (and likely) that rootViewController will be released before you can call methods on it.
This is a good time to use delegates. You mention calling a method "in the delegate" but without seeing any of your code it's difficult to tell if you're using it correctly or not.

Passing info from Facebook to UITabBarController

When my app first starts, it shows a main page to log in to Facebook. Then, it goes to the UITabBarController. The code that I have in my app delegate is the following:
//this is the .h
#interface NMeAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
MainViewController *controller;
UITabBarController *tabBar;
}
#property (nonatomic, retain) IBOutlet UITabBarController *tabBar;
#property (nonatomic, retain) MainViewController *controller;
#property (nonatomic, retain) IBOutlet UIWindow *window;
#end
//this is the .m of the app delegate
#import "NMeAppDelegate.h"
#implementation NMeAppDelegate
#synthesize window;
#synthesize tabBar;
#synthesize controller;
#pragma mark -
#pragma mark Application lifecycle
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
controller = [[MainViewController alloc] init];
[window addSubview:tabBar.view];
[window addSubview:controller.view];
[window makeKeyAndVisible];
return YES;
}
Inside of MainViewController, I actually have a UserInfo object, which has all of the information that I need for the UITabBarController. The problem is that after getting this info in the UITabViewController, how do I pass this UserInfo to the UITabBarController` or possible the ViewController that is inside the UITabBarController so they were able to access this UserInfo? How to do this?
I hope my question makes sense.
you need to have an instance of your UserInfo object available to the tab bar controller. probably pass it into a instance variable of type UserInfo in your UItabBarController/each view controller whenever you transition into the specified controller.
edit: you should really have this passed into the view Controller it needs to be in (since it doesn't appear you have a custom UITabBarController subclass), or you could use a shared UserInfo variable in your app delegate to keep up with the information.
But as the commenter said, the question is not very clear at all and i could be completely misunderstanding what you want to do.
Hope that helps.

Using Navigation Controller in a subview of View based Applicatin

Some one please help me with this. I am developing an iPhone app and have stared with View Based Application. I have buttons on my root view screen to take user to other views with their own nibs and classes. On one of those views I need to display a table getting data from SQLite database and then display detail of the selected item depending on the selection from the table. At later stage I also need to add forms to add data.
Now, how to add a Navigation Controller in that view for drill down? Can we convert a View Controller to Navigation Controller just by adding a Navigation bar at the top?
sure
in viewbase application, u can create navigation controller
add the code in delegate.h
#interface test24AppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
test24ViewController *viewController;
UINavigationController *nav;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet test24ViewController *viewController;
#property (nonatomic, retain) IBOutlet UINavigationController *nav;
#end
add this delegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
nav=[[UINavigationController alloc]init];
[nav pushViewController:viewController animated:YES];
[self.window addSubview:nav.view];
[self.window makeKeyAndVisible];
return YES;
}
now it will work, u check using nslog(#"%#", self.navigationController); if the result is null then u have problem still.

Calling a function from another UIViewController

I'm a beginner programmmer, this is for xcode - iPhone. although i made alot of my iPhone app but i seem to lack some understanding of how a simple communication might work.
Specially when I've got 2 ViewControllers.
And I wana call one function of a ViewController from another ViewController. Both are under a tabbarController. What I want to achieve is When I'm in ViewA, after tapping on a tableCell, I Should Invoke a method of ViewB and the NavigationBar of ViewB pushes to viewDetail.
The Following is the code i'm using
in ViewControllerA.h (where I'm calling a method)
#class ViewControllerB;
#interface SmartDDxViewController : UIViewController {
IBOutlet UITableView *tableView;
ViewControllerB *xViewController;
}
#property (nonatomic, retain) UITableView *tableView;
#property (nonatomic, retain) ViewControllerB *xViewController;
And this is what I use to invoke it..ViewControllerA.m
ViewControllerB *ddViewController = [[ViewControllerB alloc] init];
self.xViewController = ddViewController;
[xViewController InitialiseDetailWithId:2 title:#"HEYA"];
Heres the InitialiseDetailWithId code: in ViewControllerB.m
-(void)InitialiseDetailWithId:(NSInteger)pkey title:(NSString *)tt{
NSLog(#"InitialiseDetailC=========================================");
AppDelegate *appDelegate = (Smart_DifferentialsAppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate GetConditionDetailsWithId:pkey];
DDisViewController *viewController= [[DDisViewController alloc] initWithNibName:#"DetailView" bundle:nil];
viewController.title = tt;
[self.NavBar pushViewController:viewController animated:YES];
//[tt release];
[viewController release];
viewController = nil;
[self say:#"HEYA"]; //this is ALERTVIEW box that displays HEYA
}
I'm getting all information fine, and the alertview does get displayed. But when I chose that View in TabBar, its not pushed.
Do not use direct access between view controllers, instead use the delegate pattern. Define your controller like this:
#protocol ViewControllerAInitDelegate;
#interface ViewControllerA : UIViewController {
IBOutlet UITableView *tableView;
id<ViewControllerAInitDelegate> initDelegate;
}
#property (nonatomic, retain) UITableView *tableView;
#property (nonatomic, assign) ViewControllerAInitDelegate *initDelegate;
#end
#protocol ViewControllerInitDelegate
-(void)initializeDetailWithId:(NSInteger)pkey title:(NSString)tt;
#end
So in
Now let your application delegate conform to the ViewControllerInitDelegate protocol. It should look something like this:
#interface AppDelegate : NSObject <UIApplicationDelegate, ViewControllerInitDelegate> {
IBOutlet UITabBarControler* tabBarController;
IBOutlet ViewControllerA* controllerA;
IBOutlet ViewControllerB* controllerB;
}
#end;
The AppDelegate should know about both ViewControllerA, and ViewControllerB, but neither of the view controller should know about each other. This way it will be much easier to debug and extend your app.
//current view controller index
int currentVCIndex = [self.navigationController.viewControllers indexOfObject:self.navigationController.topViewController];
//previous view controller (index -1)
AccountViewController *account = (AccountViewController *)[self.navigationController.viewControllers objectAtIndex:currentVCIndex - 1];
(access to anything you want)
account.property = object;
[account doSmthng];
In each of your view controllers, you might want to add a instance variable/property to keep track of the other view controller.
you might have for example:
#interface ThisViewController : UIViewController {
SomeViewController *sViewController;
// other instance variables
}
#property (nonatomic, retain) SomeViewController *sViewController;
This not only makes it easier to call methods from the other view controller and access its public properties, but it also allows you an easier way of flipping between the two (with or without animation).

Where is the UIWindow instantiated in an iPhone app?

When you create an application from the "View-Based" template in the iPhoneSDK the following code is generated. I basically understand what is happening here, but I do not see where window and viewController are instantiated. Any Help?
#class jojojViewController;
#interface jojojAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
jojojViewController *viewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet jojojViewController *viewController;
#end
===============================================
#implementation Test6AppDelegate
#synthesize window,mainView;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
// Override point for customization after application launch
[window makeKeyAndVisible];
}
- (void)dealloc {
[window release];
[super dealloc];
}
#end
They come from the MainWindow.xib (or similar) file in your project.
This is the file that in your info.plist is set as the application window. When your application starts this xib is loaded and the viewcontroller and window are unarchived and loaded.
If you look in MainWindow.xib, the window and viewcontroller are assigned to your AppDelegate's window and viewController outlets, which instantiates them when the nib is loaded (right click on the AppDelegate to see it).