连接起来:AppDelegate、ViewController和XIB

9

我是iOS编程的新手,遇到了一个问题。

做了什么:

我创建了iOS应用程序。最初它有main.m、AppDelegate.h、AppDelegate.m和一些其他支持文件(不带代码)通常会被创建。

然后我手动创建了具有界面的XIB文件(LoginView.xib),并手动添加了LoginViewController.h和LoginViewController.m以控制XIB。

在LoginViewController.h中添加了outlets。

最后,我设置了文件所有者类(LoginViewController)并在XIB和LoginViewController.h之间建立了连接。

问题描述:

我需要在应用程序启动时立即显示登录视图控制器并显示登录视图。

我尝试了几次并阅读了数十个论坛主题,但是没有办法。除了白色窗口背景以外什么都没有显示。我该如何才能正确地做到这一点?

参考代码:

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;
}

更新!!! 大家好,多亏了你们,我发现了另一个问题。在经过适当编辑后,您批准我的代码正确无误之后,我启动模拟器,结果发现我的应用程序崩溃,并出现以下异常:

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

感谢StackOverflow,我解决了这个问题。 Loaded nib but the view outlet was not set - new to InterfaceBuilder 以下是Josh Justice在我提供的链接中评论的引用:
  1. 打开导致问题的XIB文件
  2. 单击左侧栏上的文件所有者图标(顶部一个,看起来像一个带黄色轮廓的盒子)
  3. 如果您没有看到右侧边栏,请单击工具栏中“视图”上方的第三个图标。这将显示右侧边栏
  4. 在右侧边栏中,单击第三个选项卡 - 稍微像报纸的那一个
  5. 在顶部的“自定义类”下,请确保“类”是应与此视图对应的ViewController的名称。如果不是,请输入
  6. 在右侧边栏中,单击最后一个选项卡 - 看起来像一个圆圈带有箭头
  7. 您应该看到带有“视图”下方的“插座”。将其旁边的圆圈拖到左侧栏上的“视图”图标上(底部一个,看起来像带有浓密灰色轮廓的白色正方形)
  8. 保存xib并重新运行
可能将这些信息汇总到一个要点中,将有助于其他新手更快地通过我所经历的过程。

大家好,现在我的登录视图在启动时已经完美显示了,但我遇到了另一个问题:文本框无法编辑 :( 我点击文本框,光标出现在其中,但无法输入字符(甚至键盘也不弹出),也无法将焦点切换到另一个文本框。你们有什么建议吗?谢谢! - nickolay
还有一个问题:我真的需要这个IBOutlet吗:IBOutlet UIView *_loginView;? - nickolay
3个回答

8
在你的应用程序的application:didFinishLaunchingWithOptions:方法中,将LoginViewController设置为你的根视图控制器。
self.window.rootViewController = self.loginViewController;

请移除这行文字:

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

2

在您的AppDelegate.m文件中,您需要像这样设置rootViewController

self.window.rootViewController = self.loginViewController;

感谢您的回答,很抱歉没有将其标记为实际答案。bvogelzang的回答更加精确。 - nickolay

0

你有使用storyboards创建界面的经验吗?(自iOS 5以来,Storyboards是新功能)它们基本上是一种在一个文件中布置所有视图控制器并在它们之间可视化设置连接的方式。使用storyboards实现你想要的功能非常容易。当你在storyboard文件中设置视图控制器时,你会看到一个箭头指向你设置的第一个storyboard。这意味着当你运行你的应用程序时,它将加载初始视图。如果你希望不同的视图首先加载,只需将该箭头拖动到另一个视图控制器即可。


Ryan,谢谢。当然,我会学习这个技巧。这次我想要了解“它是如何工作的”。所以请原谅我的愚蠢问题。 - nickolay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接