pushViewController,何时设置UILabel文本,并且需要调用setNeedsDisplay吗?

时间:2011-10-11 16:33:42

标签: iphone uiview uiviewcontroller

我今天遇到了一些奇怪的事情,也许有人知道一些事情。我有一个UIViewController的子类及其相关的NIB。我在UIViewController方法中设置标签,一切正常。

现在从另一个类,我再次创建ViewController,因为我想重用它。我这样做:

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

NOT 工作。我不知道为什么这不起作用。我想我会设置所有标签,然后通过将它推到堆栈上来显示视图控制器。

但是,如果我这样做:

[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];

DOES 工作。这对我来说没有意义。我认为在需要重绘视图后调用setNeeds Display。如果我将setNeedsDisplay移动到块的末尾它不起作用。它只适用于块的开头,这对我来说非常奇怪。任何人之前遇到过这种情况或者知道它为什么会这样运作?感谢。

1 个答案:

答案 0 :(得分:7)

原因是视图控制器的视图是延迟加载的。这意味着当您第一次访问-loadView属性时,控制器的视图仅从笔尖(或通过view)加载。如果您在加载视图之前尝试访问标签,它们将为零,并且您发送给它们的任何消息都将是no-ops。

因此,要强制加载视图,您可以执行以下操作:

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

但是,在所有情况下强制加载视图可能不是一个好主意,特别是如果视图控制器不会立即显示并且您想要节省内存。

在这种情况下,您可以在控制器的init方法中创建标签,使它们始终存在,并在-viewDidLoad中手动将其添加到视图控制器的视图中,而不是在您的笔尖中。这将允许标准的延迟加载行为起作用,但是在加载视图之前,类的用户仍然可以在标签上设置属性。

另一种方法是在视图控制器上公开具有关联ivars的简单NSString属性,以表示视图中的任何标题或文本。然后在-viewDidLoad中,您可以将标签文本设置为这些属性的值。然后,视图控制器的用户可以在加载视图之前设置这些属性。