web-dev-qa-db-ja.com

コンストラクターであるViewDidAppear、ViewDidLoad、ViewWillAppearにサブビューをプログラムで追加しますか?

私はAppleの sketchy ドキュメントから、Viewsコントロールを初期化してコントローラーのビューに追加するのに最適な方法を見つけようとしています。

Winformsを使用すると、コンストラクターで呼び出されるInitializeDesigner内で常に初期化されるため、かなり簡単です。可能であれば、このパターンの信頼性を一致させようとしています。

私はほとんどの場合、UIViewControllers内でUITableViewControllersUINavigationControllerを使用しています-これがすべてに影響する場合。

次に例を示します。

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);
}

さまざまな場所のビューに追加すると、いくつかのUIControlで混合結果が得られます。視覚的な遅れがある場合もあれば、Webビューがどこかに隠されている場合もあります。

それらを追加するために守るべき一般的なルールはありますか?

25
Chris S

一般的に、これは私がしていることです:

  • ViewDidLoad-ビューと一緒に表示されるはずのコントロールをビューに追加するときはいつでも、すぐにViewDidLoadメソッドに配置します。基本的に、このメソッドは、ビューがメモリにロードされるたびに呼び出されます。したがって、たとえば、ビューが3つのラベルを持つフォームである場合、ここにラベルを追加します。これらのフォームがないと、ビューは存在しません。

  • ViewWillAppear:通常、フォームのデータを更新するためだけにViewWillAppearを使用します。したがって、上記の例では、これを使用して、ドメインからフォームにデータを実際にロードします。 UIViewsの作成にはかなりの費用がかかります。これは、ViewWillAppearメソッドで行うことをできるだけ避ける必要があります。これは、呼び出されたときに、iPhoneがすでにUIViewをユーザーに表示する準備ができていることを意味します。非常に目に見える形でパフォーマンスに影響を与えます(アニメーションの遅延など)。

  • ViewDidAppear:最後に、ViewDidAppearを使用して、実行に時間がかかるものへの新しいスレッドを開始します。たとえば、上記のフォームの追加データを取得するためにWebサービス呼び出しを実行します。ビューはすでに存在し、ユーザーに表示されているため、データを取得している間、ユーザーに「待機中」というメッセージを表示できます。

ただし、使用できるトリックは他にもあります。フォームがロードされた後、UILabelをフォームに「飛ばす」ようにするとします。その場合、ViewDidLoadのフォームにラベルを追加しますが、フレームはビュー領域の外側にあり、ViewDidAppearでアニメーションを実行して、ビューにフライバックします。

それが役に立てば幸い。

73
Eduardo Scoz

うーん、Appleのドキュメントはかなり明確なようです、私見。

独自のルートビュー(この特定のコントローラーのビュー階層のルートビュー)をプログラムで作成する場合は、superを呼び出さずに-loadViewで作成し、完了したらviewプロパティを設定する必要があります。 。ビューがペン先から読み込まれる場合は、-loadViewに触れないでください。

カスタムサブビューをビューコントローラのビューに追加するか、-viewDidLoadで変更します。推奨される方法は、UILabelとUIWebViewを-viewDidLoadで作成し、それらを-viewDidUnloadで解放し、それらをivarに保持する必要がある場合は、参照をnilに設定することです。

注:-viewDidUnloadはiOS6で非推奨になり、UIViewControllerがメモリ不足でビューをパージしなくなったため、呼び出されなくなりました。

9
Costique

viewDidLoadは「MEMORY」に関連し、viewWillAppear/viewDidAppearは「APPEARANCE」に関連します。ビューコントローラのビュー(ビューコントローラのビューのルートビュー)は、コントローラのビューがすでにメモリにある場合でも、何度も表示/非表示になる可能性があります。

(ルートビューを参照する場合、ルートビューはその子(サブビュー)を参照するため、サブビューも意味しますが、ビューコントローラの観点からは、通常はルートビューのみを認識します。サブビューへの参照は通常どおり発生します。ビューコントローラのコンセントを介して。)

メモリ警告がある場合、ルートビュー自体がメモリから削除される場合があります。ビューコントローラは、それらをメモリから削除するのに最適な時期を決定します。

したがって、サブビューを追加することはそれらをメモリに追加することを意味するため、通常はviewDidLoadにサブビューを追加します。ただし、すべてのビューをプログラムで作成する場合はそうではありません(nibファイルからではありません)。その場合は、loadViewメソッドをオーバーライドし、ルートビューを作成してそこにサブビューを追加する必要があるため、この場合、viewDidLoadを省略してサブビューを追加できます。

2
Coolant