web-dev-qa-db-ja.com

UIViewControllerでのサブビューのレイアウトとサイズ変更

アプリにはUITabControllerがあり、各タブはUINavigationControllerです。私のUINavigationControllersの1つのルートはUIViewControllerです。

そのView Controllerのビュー内で、いくつかのサブビューをレイアウトしたいのですが、解像度に依存しない方法でそれらをレイアウトする場所と方法について混乱しています(つまり、320px、480px、44pxなどの値をハードコードしません) )。

ビューが完全にロードされて垂直のiPhoneに表示されると、その高さは367px = 480-20(ステータスバー)-44(ナビゲーションバー)-49(タブバー)になります。

現在、View Controller内で、viewDidLoadメソッド内にすべてのサブビューを作成しています。ただし、このメソッド内では、ビューの現在の高さは460px(self.view.bounds.size.height)のようです。したがって、サブビューを設定するときに、何かのサイズを適切に計算できません。

viewWillAppear:メソッド内で、ビューdoesは適切なサイズであることを認識しますが、ビューが表示されるたびにサブビューのフレームを設定および計算することを意味します(たとえば、タブの変更または子View Controllerからのポップナビゲーションスタック上。

これをviewWillAppear:のレイアウトに適切に行う唯一の方法ですか?

自動サイズ変更プロパティ(親のautoresizesSubviewsautoresizingMask)を使用しようとしましたが、まったく機能しないようです!?これらは、ビューがすべて設定されてからサイズが変更された場合にのみ有効になります(手動/方向の変更?)。

自動サイズ変更が機能しない理由と、サイズをハードコーディングしないことで物事をレイアウトする最善の方法を誰かに教えていただければ幸いです。

49

autoresizesSubviewsは親ビューで設定する必要があり、autoresizingMaskは子ビューで設定する必要があります-これも私が犯した間違いです。

loadViewでは、現在の親ビューのサイズに合わせてサブビューのサイズを変更する必要があります。その後、親ビューのサイズが460から367ピクセルに変更されると、サブビューのサイズも変更されます。上記のマスク設定。

それが失敗した場合、ビューサイズをviewWillAppear内に設定するのに何も問題はありません。毎回行うことによるパフォーマンスへの影響は無視できます。

他に機能しない場合は、常にlayoutSubviews:-必要に応じて手動レイアウトを行うことができます。レイアウトを変更する必要があるとシステムが判断したときに呼び出されます。 setNeedsLayoutもあります:私は時々viewWillRotate:/viewDidRotate:など。しかし、実際にはこれは必要ではなく、自動サイズ変更で十分です。

編集:はい、上で述べたようにlayoutSubviewsにカスタムレイアウトロジックを実装するには、UIViewをサブクラス化する必要があります。

35
DenNukem

viewWillLayoutSubviewsUIViewController内でレイアウトロジックを実行できます。

-(void)viewWillLayoutSubviews{
    [super viewWillLayoutSubviews];
    // Your layout logic here
}

DOC:View ControllerのビューのlayoutSubviewsメソッドが呼び出される直前に呼び出されます。サブクラスは必要に応じて実装できます。デフォルトはnopです。

43
aumanets