从 NIB 加载后 IBOutlet 实例为 (null)

发布于 2024-08-01 15:54:14 字数 1089 浏览 13 评论 0原文

我正在开发一个 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)"

I am working on an iPhone app and am getting (null) references to IBOutlet fields in my controller. I have a UIViewController subclass that is set as the File's Owner in my XIB. I have a set of UI elements that are wired into the controller. After loading from NIB and attempting to set properties on those UI elements, I find that they are (null). To clarify, some code:

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 is set as the File's Owner for ExpandSearchPage.xib. ExpandSearchPage.xib's UITextView is wired to the completeMessageView.

When I call

ExpandSearchPageController * searchExpanderPage = [[ExpandSearchPageController alloc] initWithNibName:@"ExpandSearchPage" bundle:[NSBundle mainBundle]];

[searchExpanderPage checkTextField];

the result is

"text field: (null)"

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

淡墨 2024-08-08 15:54:14

我想在查看问题一个多小时后提出问题让我弄清楚:

我只是更改了代码以在显示视图后检查文本框......现在一切都已实例化。

想象一下:UI 元素在您显示之前不会被实例化!

I guess asking the question after looking at the problem for over an hour led me to figure it out:

I just changed my code to check the text box AFTER displaying the view... now everything is instantiated.

Imagine that: the UI elements aren't instantiated until you display them!

鲸落 2024-08-08 15:54:14

这就是解决方案。

在视图控制器完成加载之前,IBOutlet 尚未准备好使用。

例如,如果要设置 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上设置文本属性,在secondViewController.m的viewDidLoad中。
到此阶段,IBOutlet 已创建并准备就绪。

- (void)viewDidLoad {
   [super viewDidLoad];
   self.label.text = self.stringForLabel;
}

This is the solution.

The IBOutlets aren't ready to use until the view controller finishes loading.

For example, if you want to set a UILabels text property, you would need to set a NSString on your controller first, and then set the labels text property in somewhere like viewDidLoad.

So in your firstViewController.m : (This is for storyboards, but same idea applies)

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

Then in the .h of your secondViewController:

@property (strong, nonatomic) IBOutlet UILabel *label;
@property (strong, nonatomic) NSString *stringForLabel;

Then we set the text property on the UILabel, in the viewDidLoad of secondViewController.m.
By this stage, the IBOutlet has been created and is ready to go.

- (void)viewDidLoad {
   [super viewDidLoad];
   self.label.text = self.stringForLabel;
}
淑女气质 2024-08-08 15:54:14

IBOutlet 指针为空的另一个潜在原因是在创建插座连接后忘记在 Interface Builder 中保存 xib 文件。

Another potential cause of a null IBOutlet pointer is forgetting to save the xib file in Interface Builder after creating the outlet connection.

各空 2024-08-08 15:54:14

确保视图控制器的视图属性(即本例中的文件所有者)已连接到 xib 中的视图。 由于您的 textField 几乎肯定是其子视图,因此将其连接起来也很重要(而且我认为如果没有设置,笔尖将无法正确加载)。

Make sure the view property of your view controller (ie File's Owner in this case) is wired to the view in your xib. As your textField is almost certainly a subview of that, it's important to get that wired in too (and I don't think the nib will load properly without that being set).

风追烟花雨 2024-08-08 15:54:14

我就是这样做的:

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

This is how I do it:

//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];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文