开发者

pushViewController, when to set UILabel text, and does setNeedsDisplay need to be called?

I ran into something odd today that maybe someone knows something about. I have a subclass of UIViewController and its associated NIB. I set the labels in the UIViewController methods and all that works fine.

Now from another class, I create that ViewController again because I want to reuse it. I do this:

MyViewController *vc = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];
vc.titleLabel.text = @"testing";
vc.myTextLabel.text = @"yo";
self.navigationController pushViewController:vc animated:NO];
[vc release];

This does NOT work. I have no idea why this does not work. I would think I would set all the labels, then show the view controller by pushing it onto the stack.

However, if I do this:

[vc.view setNeedsDisplay]; // why here???
MyViewController *vc = [[MyViewController alloc] initWithNibName:@"MyViewController" bundle:nil];
vc.titleLabel.text = @"testing";
vc.myTextLabel.text = @"yo";
self.navigationController pushViewController:vc animated:NO];
[vc release];

This DOES work. This does not make sense to me. I thought setNeeds Display was ca开发者_JAVA百科lled AFTER a view needs to be redrawn. If I move setNeedsDisplay to the end of the block it does NOT work. It only works at the beginning of the block which is very odd to me. Any one encounter this before or know why it works this way? Thanks.


The reason is that a view controller's view is lazily-loaded. This means the controller's view is only loaded from a nib (or via -loadView) when you access the view property for the first time. If you attempt to access the labels before the view has been loaded, they will be nil and any messages you send to them will be no-ops.

So to force the view to load, you can do this:

/* make sure the view is loaded */
[vc view];
/* Access the label properties */
vc.titleLabel.text = @"testing";

However, forcing the view to load may not be a good idea in all situations, especially if the view controller is not going to be displayed immediately and you want to save memory.

In this case you can create the labels in the controller's init method so they always exist, and add them to the view controller's view manually in -viewDidLoad, rather than in your nib. This will allow the standard lazy-loading behaviour to work, but users of your class can still set properties on the labels before the view is loaded.

An alternative is to expose simple NSString properties with associated ivars on the view controller to represent any titles or text in the view. Then in your -viewDidLoad you can set the text of the labels to the value of these properties. Users of your view controller can then set these properties before the view has loaded.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜