Connect together: AppDelegate, ViewController and XIB

nickolay picture nickolay · Mar 13, 2013 · Viewed 14.6k times · Source

I am new to the iOS programming and got stuck with one problem.

What was done:

I have created iOS application. Initially it had main.m, AppDelegate.h, AppDelegate.m and some other supporting files (not with code) that are usually created.

Then I manually created XIB file with interface (LoginView.xib) and manually added LoginViewController.h and LoginViewController.m to control XIB.

Added outlets to LoginViewController.h.

After all I set up file's owner class (LoginViewController) and made connections between XIB and LoginViewController.h.

Problem description:

I need to show instantiate login view controller and show login view immediately at the application's start.

I tried several attempts and read a dozen of forum threads, but no way. Nothing is shown except white window background. How can I do it correct?

Reference code:

LoginViewController.h

#import <UIKit/UIKit.h>

@interface LoginViewController : UIViewController
{
    IBOutlet UIView        *_loginView;
    IBOutlet UITextField   *_tfLogin;
    IBOutlet UITextField   *_tfPassword;
    IBOutlet UIButton      *_btnLoginToSystem;
}

- (IBAction)attemptLogin:(id)sender;

@end

LoginViewController.m

#import "LoginViewController.h"

@interface LoginViewController ()

@end

@implementation LoginViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)attemptLogin:(id)sender
{

}

@end

AppDelegate.h

#import <UIKit/UIKit.h>
#import "LoginViewController.h"

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) LoginViewController *loginViewController;

@end

AppDelegate.m

#import "AppDelegate.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.window.backgroundColor = [UIColor whiteColor];
    self.loginViewController = [[LoginViewController alloc] initWithNibName:@"LoginView" bundle:nil];
    [self.window.rootViewController presentModalViewController:self.loginViewController animated:NO];

    [self.window makeKeyAndVisible];
    return YES;
}

UPDATE!!! Guys, thanks to you all I've found another issue. Once I got your approve that my code (after appropriate edition, of course) is correct, I started simulator and saw that my app crashes with the following exception:

NSInternalInconsistencyException with the reason [UIViewController _loadViewFromNibNamed:bundle:] loaded the ... nib but the view outlet was not set.

Thanks to StackOverflow I fixed it. Loaded nib but the view outlet was not set - new to InterfaceBuilder

Quotation of Josh Justice comment from the topic I provided link to:

  1. Open the XIB file causing problems
  2. Click on file's owner icon on the left bar (top one, looks like a yellow outlined box)
  3. If you don't see the right-hand sidebar, click on the third icon above "view" in your toolbar. This will show the right-hand sidebar
  4. In the right-hand sidebar, click on the third tab--the one that looks a bit like a newspaper
  5. Under "Custom Class" at the top, make sure Class is the name of the ViewController that should correspond to this view. If not, enter it
  6. In the right-hand sidebar, click on the last tab--the one that looks like a circle with an arrow in it
  7. You should see "outlets" with "view" under it. Drag the circle next to it over to the "view" icon on the left bar (bottom one, looks like a white square with a thick gray outline
  8. Save the xib and re-run

Probably this information aggregated into one point will help other newcomers to pass the way I passed faster.

Answer

bvogelzang picture bvogelzang · Mar 13, 2013

Set the LoginViewController as your root view controller in your application:didFinishLaunchingWithOptions: method.

self.window.rootViewController = self.loginViewController;

remove this line:

[self.window.rootViewController presentModalViewController:self.loginViewController animated:NO];