1
votes

I have a login view and after checking the username i want to go to a table view. I downloaded the SimpleDrillDown App from apple sample codes, and i want when i run the application to first view the login page and after that the TableView.

If someone has the time the project can be found here : http://developer.apple.com/iphone/library/samplecode/SimpleDrillDown/index.html

The changes that i had made are:

SimpleDrillDownAppDelegate.m

import "SimpleDrillDownAppDelegate.h"
import "RootViewController.h"
import "LoginViewController.h"
import "DataController.h"


@implementation SimpleDrillDownAppDelegate

@synthesize window;
@synthesize navigationController;
@synthesize rootViewController;
@synthesize loginViewController;
@synthesize dataController;


- (void)applicationDidFinishLaunching:(UIApplication *)application {
    
   
    //thomas add this
    LoginViewController *_loginViewController = [[LoginViewController alloc] initWithNibName:@"LoginView" bundle:[NSBundle mainBundle]];
    self.loginViewController = _loginViewController;
//  [_loginViewController release];
//  
    //thomas add this
    
    // Create the data controller.
    //DataController *controller = [[DataController alloc] init];
//    self.dataController = controller;
//    [controller release];
    
    //rootViewController.dataController = dataController;
    
    /*
     The navigation and root view controllers are created in the main nib file.
     Configure the window with the navigation controller's view and then show it.
     */
    //thomas commented this and copy this into LoginView
    //[window addSubview:[navigationController view]];
    
    //thomas add this
    [window addSubview:[loginViewController view]];
    //thomas add this
    
    
    [window makeKeyAndVisible];
}


- (void)dealloc {
    //[navigationController release];
    //[rootViewController release];
    [loginViewController release];
    [window release];
    //[dataController release];
    [super dealloc];
}

@end

SimpleDrillDownAppDelegate.h

@class DataController;
@class RootViewController;
@class LoginViewController;

@interface SimpleDrillDownAppDelegate : NSObject  {
    
    UIWindow *window;
    
    UINavigationController *navigationController;
    RootViewController *rootViewController;
    LoginViewController *loginViewController;
    
    DataController *dataController;
}

@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
@property (nonatomic, retain) IBOutlet RootViewController *rootViewController;
@property (nonatomic, retain) IBOutlet LoginViewController *loginViewController;

@property (nonatomic, retain) DataController *dataController;

@end

LoginViewController.h

#import 

@class DataController;
@class RootViewController;
@class LoginViewController;

@interface LoginViewController : UIViewController {
    DataController *dataController;
    IBOutlet UITextField *usernameField;
    IBOutlet UITextField *passwordField;
    IBOutlet UIButton *loginButton;
    IBOutlet UIActivityIndicatorView *loginIndicator;
    UINavigationController *navigationController;
    RootViewController *rootViewController;
    
    
}

@property (nonatomic, retain) UITextField *usernameField;
@property (nonatomic, retain) UITextField *passwordField;
@property (nonatomic, retain) UIButton *loginButton;
@property (nonatomic, retain) UIActivityIndicatorView *loginIndicator;
@property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
@property (nonatomic, retain) DataController *dataController;
@property (nonatomic, retain) IBOutlet RootViewController *rootViewController;


- (IBAction) login: (id) sender;

@end

LoginViewController.m

#import "LoginViewController.h"
#import "DataController.h"
#import "RootViewController.h"




@implementation LoginViewController

@synthesize usernameField;
@synthesize passwordField;
@synthesize loginButton;
@synthesize loginIndicator;
@synthesize navigationController;
@synthesize dataController;
@synthesize rootViewController;


/*
 // The designated initializer.  Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
        // Custom initialization
    }
    return self;
}
*/

/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/

/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    [super viewDidLoad];
}
*/

/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
    // Return YES for supported orientations
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
*/

- (void)didReceiveMemoryWarning {
    // Releases the view if it doesn't have a superview.
    [super didReceiveMemoryWarning];
    
    // Release any cached data, images, etc that aren't in use.
}

- (void)viewDidUnload {
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
}


- (void)dealloc {
    [super dealloc];
}

- (IBAction) login: (id) sender
{
    // TODO: spawn a login thread
    NSString *userName = usernameField.text;
    NSString *pass = passwordField.text;
    
    loginIndicator.hidden = FALSE;
    [loginIndicator startAnimating];
    
    loginButton.enabled = FALSE;
    
    //Hardcode here the credentials
    
    
    
    if ([userName isEqualToString: @"test"] && [pass isEqualToString: @"test"]){
    // Create the data controller.
    DataController *controller = [[DataController alloc] init];
    self.dataController = controller;
    [controller release];
  
    rootViewController.dataController = dataController;
    
    
  [self pushViewController:self.navigationController animated:YES];
    }else{
        printf("ERROR");
    }
    
    
    
}


@end

Finally i get this error

Error Log

2010-02-24 21:19:55.595 SimpleDrillDown[97651:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[LoginViewController pushViewController:animated:]: unrecognized selector sent to instance 0x190d8a0'
2010-02-24 21:19:55.595 SimpleDrillDown[97651:207] Stack: (
    807902715,
    2501092617,
    808284155,
    807854166,
    807706786,
    18813,
    814709201,
    815110321,
    815119058,
    815114808,
    814812979,
    814722763,
    814748641,
    839148405,
    807687520,
    807683624,
    839142449,
    839142646,
    814752238,
    9140,
    8994
)

Sorry for the long post but i don't know where else to search i have read a tone of post in here :(

Thanks in advance all of you

3

3 Answers

0
votes

In your login IBAction, send the LoginViewController the pushViewController: animated: message. That message and its counter-part, popViewControllerAnimated: is available in the UINavigationController class.

Unfortunately, your LoginViewController isn't a UINavigationController.

You can fix that particular error by changing it to:

[self.navigationController pushViewController:self.dataController animated:YES];

That assumes that LoginViewController is being hosted by a UINavigationController.

0
votes

Giao is right. you need to tell a navigationController to push the view, not a viewController subclass. the navigationController should be handling all your view controllers that you want for the hierarchically structured part of your application. your navigationController should use its initWithRootViewController: method first to load your logincontroller and show its view. then when you want to display the next view, you send the navigtionController the pushViewController:animated: message with the next viewController who's view you want to display.

0
votes

Another approach would be to create your first view as the Navigation Controller holding the UITableView and then on viewWillAppear, you check to see if the user has logged in. If they are not yet logged in, present the LoginViewController you create as modal. The benefit of using the modal is the root view will be your tableview. If your app has a tabbar and your first navigation controller view is the loginview controller, each time you hit the tab bar item, your login view will display.

Hope this helps.