Соедините вместе: AppDelegate, ViewController и XIB

Я новичок в программировании iOS и столкнулся с одной проблемой.

Что было сделано:

Я создал iOS-приложение. Изначально у него были main.m, AppDelegate.h, AppDelegate.m и некоторые другие вспомогательные файлы (не с кодом), которые обычно создаются.

Затем я вручную создал файл XIB с интерфейсом (LoginView.xib) и вручную добавил LoginViewController.h и LoginViewController.m для управления XIB.

Добавлены выходы в LoginViewController.h.

В конце концов, я настроил класс владельца файла (LoginViewController) и установил соединения между XIB и LoginViewController.h.

Описание проблемы:

Мне нужно показать экземпляр контроллера представления входа в систему и показать представление входа сразу при запуске приложения.

Пробовал несколько раз и перечитал с десяток тем форума, но никак. Ничего не отображается, кроме белого фона окна. Как я могу сделать это правильно?

Код ссылки:

Логинвиевконтроллер.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

Логинвиевконтроллер.м

#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 я это исправил. Загружен перо, но выход представления не был set - новое в InterfaceBuilder

Цитата комментария Джоша Джастиса из темы, на которую я дал ссылку:

  1. Откройте файл XIB, вызывающий проблемы
  2. Нажмите на значок владельца файла на левой панели (верхний, выглядит как желтый прямоугольник)
  3. Если вы не видите правую боковую панель, щелкните третий значок над «видом» на панели инструментов. Это покажет правую боковую панель
  4. На правой боковой панели нажмите на третью вкладку, которая немного похожа на газету.
  5. В разделе «Пользовательский класс» вверху убедитесь, что класс — это имя ViewController, которое должно соответствовать этому представлению. Если нет, введите его
  6. На правой боковой панели нажмите на последнюю вкладку — ту, которая выглядит как круг со стрелкой внутри.
  7. Вы должны увидеть «розетки» с «видом» под ним. Перетащите круг рядом с ним на значок «просмотр» на левой панели (нижний выглядит как белый квадрат с толстым серым контуром).
  8. Сохраните xib и перезапустите

Возможно, эта информация, собранная в один пункт, поможет другим новичкам быстрее пройти путь, пройденный мной.


person nickolay    schedule 13.03.2013    source источник
comment
Ребята, теперь, после того, как мое окно входа в систему отлично отображается при запуске, я столкнулся с другой проблемой: текстовые поля не редактируются :( Я нажимаю на текстовое поле, внутри него появляется курсор, но я не могу ни вводить символы (даже клавиатура не отображается), ни переключать фокус на другое текстовое поле. у вас есть предложения? Спасибо!   -  person nickolay    schedule 14.03.2013
comment
И еще вопрос: а нужен ли мне этот IBOutlet: IBOutlet UIView *_loginView; ?????   -  person nickolay    schedule 14.03.2013


Ответы (3)


Установите LoginViewController в качестве корневого контроллера представления в методе application:didFinishLaunchingWithOptions:.

self.window.rootViewController = self.loginViewController;

удалите эту строку:

[self.window.rootViewController presentModalViewController:self.loginViewController animated:NO];
person bvogelzang    schedule 13.03.2013

Вы должны установить rootViewController таким образом в своем AppDelegate.m.

self.window.rootViewController = self.loginViewController;
person nsgulliver    schedule 13.03.2013
comment
спасибо за ваш ответ и извините, что не пометили его как фактический ответ. Бвогельзанг еще точнее. - person nickolay; 14.03.2013

Вы уже работали над созданием своего интерфейса с раскадровками? (Раскадровки впервые появились в iOS 5). По сути, это способ размещения всех ваших контроллеров представления в одном файле и визуальной установки связей между ними. То, что вы хотите сделать, очень легко сделать с помощью раскадровки. Когда вы настраиваете контроллеры представления в файле раскадровки, вы увидите стрелку, указывающую на первую настроенную вами раскадровку. Это означает, что когда вы запускаете свое приложение, загружается начальное представление. Если вы предпочитаете, чтобы сначала загружалось другое представление, просто перетащите эту стрелку на другой контроллер представления.

person iOSAppGuy    schedule 13.03.2013
comment
Райан, спасибо. Конечно, я освою эту технику. На этот раз я хотел бы понять, как в работе. Так что задаю свой глупый вопрос. - person nickolay; 14.03.2013