我是否以编程方式在ViewDidAppear,ViewDidLoad,ViewWillAppear,构造函数中添加SubViews?

问题描述:

我试图从苹果的sketchy文档中找出哪种方法是最好的地方是初始化和添加我的视图控制到控制器的视图。我是否以编程方式在ViewDidAppear,ViewDidLoad,ViewWillAppear,构造函数中添加SubViews?

使用winforms,它非常简单,因为它们始终在InitializeDesigner内初始化,在构造函数中调用。如果可能的话,我试图匹配这种模式的可靠性。

大部分时间里,我正在与UIViewControllersUITableViewControllers一起使用UINavigationController - 如果这会影响一切。

下面是一个例子:

public MyController() 
{ 
    // Here? 
    AddViews(); 
} 

public override ViewDidLoad() 
{ 
    base.ViewDidLoad(); 

    // Or is should it be here? 
    AddViews(); 
} 

public override ViewWillAppear(bool) 
{ 
    base.ViewWillAppear(animated); 

    // Here? 
    AddViews(); 
} 

public override ViewDidAppear(bool animated) 
{ 
    base.ViewDidLoad(animated); 

    // Or maybe here? 
    AddViews(); 
} 

void AddViews() 
{ 
    UILabel label = new UILabel(); 
    label.Text = "Test"; 
    label.Frame = new RectangleF(100,100,100,26); 
    View.AddSubView(label); 

    UIWebView webview = new UIWebView(); 
    webview .Frame = new RectangleF(100,100,100,26); 
    View.AddSubView(webview); 
} 

我得到了一些UIControls混合的结果,当我将它们添加到在不同的地方查看。视觉滞后有时,othertimes webview被隐藏在某处。

是否有一个通用规则来保持添加它们?

+2

另请参阅:http://*.com/questions/573958/iphone-sdk-what-is-the-difference-between-loadview-and-viewdidload – 2010-02-17 13:05:29

在一般情况下,这是我做的:

  • viewDidLoad中 - 每当我添加控件应该与视图一起出现一个视图,马上,我把它放在viewDidLoad中方法。基本上这个方法在视图加载到内存时被调用。例如,如果我的视图是一个带有3个标签的表单,我会在这里添加标签;如果没有这些形式,视图将永远不会存在

  • ViewWillAppear:我使用ViewWillAppear通常只是为了更新表单上的数据。因此,对于上面的示例,我将使用它实际将我的域中的数据加载到表单中。创建UIViews相当昂贵,你应该尽可能地避免在ViewWillAppear方法上做这件事,因为当它被调用时,这意味着iPhone已经准备好向用户展示UIView,并且你在这里做的任何事情都很重会以非常明显的方式影响性能(如动画被延迟等)。

  • ViewDidAppear:最后,我用的是ViewDidAppear,开始一个新的线程的事情,需要很长的时间来执行,例如像做一个Web服务调用,以获得额外的数据,上面的表格。好处是,因为视图已经存在并且正在显示给用户,所以当您获取数据时,您可以向用户显示一个很好的“等待”消息。

虽然有其他的技巧可以使用。比方说,你想要一个UILabel在表单加载后“飞”到表单中。在这种情况下,我会将标签添加到ViewDidLoad中的窗体中,但在视图区域之外添加一个Frame,然后在ViewDidAppear中,我将执行动画以将其返回到视图中。

希望它有帮助。

+0

谢谢,这是清除了很多。我一直无法添加任何与这个问题的LoadView示例:http://*.com/questions/573958/iphone-sdk-what-is-the-difference-between-loadview-and-viewdidload - 做你曾经使用过这种方法吗? – 2010-02-17 15:55:44

+1

所以基本上loadView是UIViewController的一种方法(当你试图弄清这些事情时使用rosetta stone - http://tirania.org/tmp/rosetta.html)。 框架会自动在控制器中调用此方法来告诉它创建视图,然后UIViewController的默认实现将调用ViewDidLoad。虽然可以重写此方法(并确保在您执行时调用基本方法),但个人而言,我更愿意只使用viewWillLoad(在loadView之前调用)和viewDidLoad(稍后调用)。 – 2010-02-17 16:51:17

+0

@eduardo,文档建议不要打电话超级loadView – 2014-02-02 18:19:50

嗯,苹果的文件似乎很清楚,恕我直言。

如果你创建自己的根视图(这个特殊的控制器的视图层次的根视图)编程,你应该-loadView创建时不调用super并在完成后设置view属性。如果您的视图是从笔尖加载的,则不应触摸-loadView

您可以将自定义子视图添加到视图控制器的视图中,或者在-viewDidLoad中修改它。建议的做法是在-viewDidLoad中创建您的UILabel和UIWebView,并在-viewDidUnload中释放它们,如果需要将它们保留在ivars中,请将它们的引用设置为nil

注意:-viewDidUnload已在iOS 6中弃用,因为UIViewController不再在内存压力下清除其视图。

+0

谢谢我错过了这个方法。不过,我仍然觉得我列出的方法只能提供何时使用它们的非常有限的信息。即使在loadView中,所有被告知的都是*'如果您想对视图执行任何额外的初始化,请在viewDidLoad方法中执行此操作' - - 何时您需要此方法? – 2010-02-17 13:04:37

+0

loadView是从NIB加载视图层次结构的方法,或者在没有加载NIB的情况下仅创建一个空的UIView的方法。您可能需要自定义视图而不是它,在这种情况下,您会覆盖loadView。例如,UITableViewController重写此方法以创建UITableView。我经常发现自己用我自己的UIView子类来做同样的事情。 – Costique 2010-02-17 20:10:18

+0

viewDidUnload已弃用 – 2015-04-26 20:45:09

viewDidLoad与'MEMORY'有关,而viewWillAppear/viewDidAppear与'APPEARANCE'有关。即使控制器的视图已经在内存中,视图控制器的视图(它是视图控制器视图的根视图)可能会出现/消失无数次。 (当提到根视图时,我也意味着它的子视图,因为根视图具有对子视图的引用,但从视图控制器的角度来看,它通常只知道根视图。子视图通常可以通过视图控制器的网点发生。)

当存在内存警告时,可能会从内存中删除根视图本身。视图控制器将确定何时是将它们从内存中移除的最佳时间。

因此,您通常会在viewDidLoad中添加子视图,因为添加子视图意味着将它们添加到内存中。但是,如果您以编程方式创建所有视图(而不是从nib文件)。如果是这种情况,那么你应该重载loadView方法,并创建一个根视图并在那里添加子视图,所以在这种情况下,你可以省略viewDidLoad来添加子视图。