Создание нового ViewController и xib для программного отображения (с помощью addSubview)

Я пишу библиотеку для использования разработчиками для iPhone (аналогично тому, как реализован OpenFeint), и я пытаюсь создать ViewController со связанным XIB, чтобы я мог создать его экземпляр в своем коде с помощью

SplashScreenViewController *splashScreenViewController = [[SplashScreenViewController alloc] init];
UIWindow *topApplicationWindow = [self getTopWindow];
[topApplicationWindow addSubview:splashScreenViewController.view];

Однако, хотя это работает с простыми элементами управления (UIButtons и т. д.), с моим SplashScreenViewController ничего не отображается. SplashScreenViewController очень прост:

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>


@interface SplashScreenView : UIViewController {
}

@end

и реализация пуста. В моем представлении XIB (SplashScreenView.xib) я попытался установить класс владельца файла на SplashScreenViewController, что не сработало, затем я попытался сделать это так, как я видел это в OpenFeint, то есть добавить контроллер представления в IB и сделайте основной UIView его дочерним элементом и вместо этого сделайте его классом SplashScreenViewController. Вот тоже не работает (не отображает).

Мне интересно, есть ли у кого-нибудь хорошая идея о том, что мне может не хватать, или кто-нибудь может порекомендовать пошаговое руководство для создания новых ViewControllers так, как я пытаюсь.

Спасибо!


person user426856    schedule 21.08.2010    source источник


Ответы (2)


Попробуйте 2 вещи:

  1. Вызовите initWithNibName, а не просто init. Возможно, OpenFeint, о котором вы говорили, переопределял init для вызова initWithNibName , поэтому вы этого не видите.

  2. Установите SplashScreenViewController в качестве владельца файла и подключите его выход к вашему представлению в IB.

Надеюсь, поможет.

person Idan    schedule 21.08.2010
comment
init просто делает initWithNibName:nil bundle:nil. когда nibName равно nil, loadView по умолчанию использует имя класса (предположительно [[self class] description] или [self className]). - person tc.; 21.08.2010
comment
Это все еще может быть проблемой. Обратите внимание, что его xib называется SplashScreenView.xib, а его класс контроллера — SplashScreenViewController. Я предполагаю, что он неправильно написал файл m от руки, потому что иначе я не знаю, почему SplashScreenView наследует от UIViewController. - person Idan; 21.08.2010
comment
Я переписал код, чтобы он был более применим к этому вопросу, а не использовал имена, которые мне понадобятся для рефакторинга в моем проекте. Так да. имя XIB отличается от имени ViewController в реальной библиотеке. Извините за эту путаницу. Ваше предложение действительно работает. OpenFeint, кажется, делает это без использования initWithNibName:bundle:, поэтому я пока оставлю этот вопрос открытым. Если у кого-нибудь есть идеи, как это сделать без использования initWithNibName:bundle:, я отмечу это как ответ. В противном случае я проверю это. - person user426856; 23.08.2010
comment
Я не понимаю вашего нового вопроса - если сейчас все работает - в чем ваша новая проблема? Вы можете обойти вызов initWithNibName, как я указал в своем ответе, переопределив его вызовом [self init] , а внутри init вы вызываете свой initWithNibName. В любом случае, если вы используете файл пера, вам нужно где-то вызвать initWithNibName. (или, как сказал tc, он будет вызываться с параметрами по умолчанию при вызове init) - person Idan; 23.08.2010
comment
Ну, я хотел бы увидеть, как это было сделано в OpenFeint, где явное задание имени пера не было необходимо, а скорее неявно задается в Interface Builder, указав SplashScreenViewController в качестве типа. Аргументация просто для соглашения, поскольку я считаю, что разработчики обычно привыкли к тому, что он подключен (я уверен). - person user426856; 24.08.2010

Вместо [splashScreenViewController alloc] попробуйте [SplashScreenViewController alloc]. Я удивлен, что вы не получили предупреждение компилятора.

person tc.    schedule 21.08.2010
comment
Я проявил некоторую изобретательность для удобства чтения при вставке кода и опечатался в операторе alloc. На самом деле это [SplashScreenViewController alloc] в моем коде. Прости - person user426856; 23.08.2010