Экземпляры IBOutlet являются (null) после загрузки из NIB
Я работаю над приложением для iPhone и получаю (null) ссылки на поля IBOutlet в моем контроллере. У меня есть подкласс UIViewController, который установлен в качестве владельца файла в моем XIB. У меня есть набор элементов пользовательского интерфейса, которые подключены к контроллеру. После загрузки из NIB и попытки установить свойства для этих элементов пользовательского интерфейса, я нахожу, что они (null). Чтобы уточнить, некоторые код:
ExpandSearchPageController.h:
@interface ExpandSearchPageController : UIViewController
{
IBOutlet UITextView * completeMessageView;
}
-(void)checkTextField;
@property (nonatomic, retain) IBOutlet UITextView * completeMessageView;
ExpandSearchPageController.М:
@implementation ExpandSearchPageController
@synthesize completeMessageView;
-(void)checkTextField
{
NSLog(@"text field: %@",completeMessageView);
}
ExpandSearchPageController устанавливается в качестве владельца файла для ExpandSearchPage.xib. ExpandSearchPage.UITextView xib подключен к completeMessageView.
Когда я звоню
ExpandSearchPageController * searchExpanderPage = [[ExpandSearchPageController alloc] initWithNibName:@"ExpandSearchPage" bundle:[NSBundle mainBundle]];
[searchExpanderPage checkTextField];
В результате получается
"text field: (null)"
5 ответов:
Я думаю, задав вопрос после того, как я смотрел на проблему в течение часа, я понял это:
Я просто изменил свой код, чтобы проверить текстовое поле после отображения представления... теперь все инстанцировано.
Представьте себе: элементы пользовательского интерфейса не создаются до тех пор, пока вы их не отобразите!
Это и есть решение.
IBOutlets не готовы к использованию, пока контроллер вида не завершит загрузку.
Например, если вы хотите установить свойство uilabels text, вам нужно будет сначала установить NSString на вашем контроллере, а затем установить свойство labels text в каком-нибудь месте, например viewDidLoad.
Так и в вашем firstViewController.м : (это для раскадровок, но та же идея применима)
- (void)buttonPress:(id)sender { [self performSegueWithIdentifier:@"mySegue" sender:self]; } - (void)prepareForSegue(UIStoryboardSegue *)segue sender:(id)sender { SecondViewController *secondViewController = [segue destinationViewController]; secondViewController.stringForLabel = @"My Label String"; }
Затем в В.h вашего secondViewController:
@property (strong, nonatomic) IBOutlet UILabel *label; @property (strong, nonatomic) NSString *stringForLabel;
Тогда мы устанавливаем свойство text на UILabel, в viewDidLoad secondViewController.м. К этому моменту IBOutlet уже создан и готов к работе.
- (void)viewDidLoad { [super viewDidLoad]; self.label.text = self.stringForLabel; }
Еще одна потенциальная причина нулевого указателя IBOutlet-это забывание сохранить xib-файл в Interface Builder после создания подключения к розетке.
Убедитесь, что свойство view контроллера вида (в данном случае владельца файла) подключено к виду в вашем xib. Поскольку ваше текстовое поле почти наверняка является подвидом этого, важно также подключить его (и я не думаю, что перо будет загружаться должным образом без этого).
Вот как я это делаю:
//in your view controller -(void)setUp { [self.cardView layoutIfNeeded]; LearnCardPlainText *cardNib = [[[UINib nibWithNibName:@"LearnCardPlainText" bundle:nil] instantiateWithOwner:self options:nil] objectAtIndex:0]; cardNib.frame = self.cardView.frame; [cardNib setUpWithPart:learnModel]; [self.view addSubview:cardNib]; }