问题
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)"
回答1:
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!
回答2:
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;
}
回答3:
Another potential cause of a null IBOutlet pointer is forgetting to save the xib file in Interface Builder after creating the outlet connection.
回答4:
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).
回答5:
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];
}
来源:https://stackoverflow.com/questions/1258021/iboutlet-instances-are-null-after-loading-from-nib