I am having problem passing value to a IBOutlet property of destinationViewController but it works fine on ordinary property see code below
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"NewsCellToDetail"]) {
testViewController *viewController = segue.destinationViewController;
viewController.titleLabel.text = @"test"; // set the IBOutlet label text to something
NSLog(@"%@",viewController.titleLabel.text); // this will output to nil
viewController.textTest = @"testing2"; // set the property to something
NSLog(@"%@", viewController.textTest) // this will output the string testing2
}
This is the code for the header file testviewcontroller.h
#import <UIKit/UIKit.h>
@interface NewsDetailViewController : UIViewController
@property (strong, nonatomic) IBOutlet UILabel *titleLabel;
@property (strong, nonatomic) NSString *textTest;
@end
I already synthesize both the property.
Thanks for the help.
I just got the same problem recently. But when I debug it step by step, I find a possible reason. (I’m sorry I’m also new to Objective C, so my following explanation may be not that accurate and professional … My previous background is mainly web development.)
If you set a breakpoint just after the line you call
testViewController *viewController = segue.destinationViewController;when you build and run the project, you will find that the UITextField property in the destinationViewController is not allocated and initiated (memory is 0x0) at the breakpoint. Meanwhile the NSString property is already allocated and initialised (so you can set its value).
I think probably UITextfield is a child view, so it only initiates when its parent view (the destination view) is initiated. But NSString is a property that is not associated with any view, so it is allocated and initiated with the view controller which declares it.
When I do a further test of this, I find a very interesting thing: the second view is loaded during the
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)senderruns. I do a test code like below:In the first view controller .m file:
In the second view controller .m file:
Noticed that I add sequential numbers before NSLog messages. I found the final log result sequence was 1,2,3,6,4,5 rather than 1,2,3,4,5,6. And in log 3, the txtScene1 result was null (not initiated), but after log 4 (the second view was loaded), in log 5, the txtScene1 was NOT null and has been initiated. This suggested that the second view was loaded during the segue performs. So I guess that during the segue transition, the initiation sequence of the second view controller objects would be: second view controller -> NSString property (and other similar properties, like NSInteger, etc.) -> second view -> UITextfield property (and other subview properties).
So I changed my codes in the first view controller .m file as below:
This code then works fine and the value is passed directly to the UITextfield property in the second view.
Hope above explanation is clear and helpful for you.