从 NIB 加载后 IBOutlet 实例为(空)
Posted
技术标签:
【中文标题】从 NIB 加载后 IBOutlet 实例为(空)【英文标题】:IBOutlet instances are (null) after loading from NIB 【发布时间】:2009-08-11 01:09:38 【问题描述】:我正在开发一个 iPhone 应用程序,并且在我的控制器中获得了对 IBOutlet 字段的(空)引用。我有一个 UIViewController 子类,它在我的 XIB 中设置为文件的所有者。我有一组连接到控制器的 UI 元素。从 NIB 加载并尝试在这些 UI 元素上设置属性后,我发现它们是 (null)。为了澄清,一些代码:
ExpandSearchPageController.h:
@interface ExpandSearchPageController : UIViewController
IBOutlet UITextView * completeMessageView;
-(void)checkTextField;
@property (nonatomic, retain) IBOutlet UITextView * completeMessageView;
ExpandSearchPageController.m:
@implementation ExpandSearchPageController
@synthesize completeMessageView;
-(void)checkTextField
NSLog(@"text field: %@",completeMessageView);
ExpandSearchPageController 被设置为 ExpandSearchPage.xib 的文件所有者。 ExpandSearchPage.xib 的 UITextView 连接到 completeMessageView。
当我打电话时
ExpandSearchPageController * searchExpanderPage = [[ExpandSearchPageController alloc] initWithNibName:@"ExpandSearchPage" bundle:[NSBundle mainBundle]];
[searchExpanderPage checkTextField];
结果是
"text field: (null)"
【问题讨论】:
【参考方案1】:我想在看了一个多小时后提出这个问题让我想通了:
我刚刚更改了代码以在显示视图后检查文本框...现在所有内容都已实例化。
想象一下:UI 元素在您显示它们之前不会被实例化!
【讨论】:
另一个吸引我的兴趣点。当以presentViewController:animated:completion:
模态显示视图控制器时,所有 IBOutlets 将为零,直到视图出现(您发现的内容)。所以你需要通过完成块来访问它们,当viewDidAppear
在模式上被调用时,它会被调用。【参考方案2】:
这就是解决方案。
在视图控制器完成加载之前,IBOutlets 无法使用。
例如,如果要设置 UILabels 文本属性,则需要先在控制器上设置 NSString,然后在 viewDidLoad 之类的地方设置标签文本属性。
所以在你的 firstViewController.m 中:(这是用于情节提要,但同样的想法适用)
- (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";
然后在你的 secondViewController 的 .h 中:
@property (strong, nonatomic) IBOutlet UILabel *label;
@property (strong, nonatomic) NSString *stringForLabel;
然后我们设置UILabel上的text属性,在secondViewController.m的viewDidLoad中。 到此阶段,IBOutlet 已创建并准备就绪。
- (void)viewDidLoad
[super viewDidLoad];
self.label.text = self.stringForLabel;
【讨论】:
【参考方案3】:空 IBOutlet 指针的另一个潜在原因是在创建出口连接后忘记在 Interface Builder 中保存 xib 文件。
【讨论】:
我认为这是 XCode 早期版本中的一个问题—— %-R 没有自动保存。现在确实如此。仍然需要注意 +1。【参考方案4】:确保视图控制器的视图属性(在这种情况下为文件所有者)已连接到 xib 中的视图。由于您的 textField 几乎可以肯定是它的子视图,因此连接它也很重要(而且我认为如果没有设置,笔尖将无法正确加载)。
【讨论】:
【参考方案5】:这就是我的做法:
//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];
【讨论】:
以上是关于从 NIB 加载后 IBOutlet 实例为(空)的主要内容,如果未能解决你的问题,请参考以下文章
从 NIB 为 GeoLocation 加载/创建视图 - IOS 和 MapKit
UITableView (IBOutlet) 在初始数据加载后变为空