Iboutlet 인스턴스는 (NULL) NIB에서로드 한 후입니다.
-
12-09-2019 - |
문제
iPhone 앱에서 작업 중이며 컨트롤러의 iBoutlet 필드에 대한 (NULL) 참조를 받고 있습니다. 내 XIB의 파일 소유자로 설정된 UIViewController 서브 클래스가 있습니다. 컨트롤러에 연결된 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는 wompleteMessageView에 연결되어 있습니다.
내가 전화 할 때
ExpandSearchPageController * searchExpanderPage = [[ExpandSearchPageController alloc] initWithNibName:@"ExpandSearchPage" bundle:[NSBundle mainBundle]];
[searchExpanderPage checkTextField];
결과는입니다
"text field: (null)"
해결책
한 시간 이상 문제를 살펴본 후 질문을 묻는 것 같아요.
보기를 표시 한 후 텍스트 상자를 확인하도록 코드를 변경했습니다. 이제 모든 것이 인스턴스화되었습니다.
상상해보십시오 : UI 요소는 표시 할 때까지 인스턴스화되지 않습니다!
다른 팁
이것이 해결책입니다.
뷰 컨트롤러가로드가 완료 될 때까지 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;
그런 다음 SecondViewController.m의 ViewDidload에서 Uilabel에 텍스트 속성을 설정했습니다. 이 단계에서 Iboutlet은 만들어졌으며 갈 준비가되었습니다.
- (void)viewDidLoad {
[super viewDidLoad];
self.label.text = self.stringForLabel;
}
Null Iboutlet 포인터의 또 다른 잠재적 원인은 콘센트 연결을 작성한 후 인터페이스 빌더에 XIB 파일을 저장하는 것을 잊고 있습니다.
View Controller (예 : 파일의 소유자)의 뷰 속성이 XIB의 뷰에 연결되어 있는지 확인하십시오. 당신의 텍스트 필드는 거의 확실히 그것의 하위 뷰이기 때문에, 그것을 연결하는 것이 중요합니다 (그리고 NIB가 설정하지 않고 제대로로드 될 것이라고 생각하지 않습니다).
이것이 내가하는 방법입니다.
//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];
}