web-dev-qa-db-ja.com

UIViewサイズを決定する場所

概要:ビューを初期化するときに、UIViewControllerはUIViewインスタンスのサイズをどのように知る必要がありますか?

UIViewの専用の初期化メソッドは、initWithFrame:(CGRect)frameメソッドです。これにより、新しく作成されたUIViewのフレームが設定されます。このメソッドは、そのView Controllerのビューが要求された場合、UIViewController'sloadViewメソッドから呼び出すことができます。サブクラス化とビューサイズに関するUIViewController状態のドキュメント:

ビュー階層のビューを作成するときは、常にビューの自動サイズ変更プロパティを設定する必要があります。ビューコントローラが画面に表示されると、そのルートビューは通常、使用可能なスペースに合わせてサイズ変更されます。これは、ウィンドウの現在の方向やステータスバーなどの他のインターフェイス要素の存在によって異なります。

したがって、UIViewControllerインスタンスはこれらのプロパティを設定する必要があります。これまでのところ、UIViewControllerは、ビューの大きさや今後の大きさを知る必要はありません。

UIViewControllerのビューが要求され、viewプロパティがnilの場合、ViewControllerのloadViewメソッドが呼び出されます。 UIViewを初期化する必要があるため、問題が発生しましたが、ViewControllerはビューのサイズを認識していません。そのビューをどのくらいの大きさに初期化する必要がありますか?コードのどこでビューサイズを決定しますか?

ゼロrect(CGRectZero)でビューを初期化できます。

- (void)loadView {
    self.view = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
}

そして、発信者に次のようにビューフレームを設定させます。

UIViewController *viewController = [[MyUIViewController alloc] init];
// next two lines are normally combined, but for clarity they are not now
UIView *view = viewController.view;
view.frame = CGRectMake(0, 0, 200, 200);

これにより、ビューコントローラー(viewController.view)からビューが要求され、loadViewメソッドを使用してビューが読み込まれます。このloadViewメソッドは、ビューをCGRectZeroで初期化します。次に、呼び出し元はフレームを設定します(view.frame = ...)

重要なのは、ビューのフレームプロパティが2回設定されているため、カスタムUIViewがsetFrameメソッドで高度なレイアウト(サブビューの配置やサイズ変更など)を行っている場合は、さらに二重の作業が発生する可能性があります。これを防ぐには、UIViewController専用の初期化メソッドを作成します。このメソッドは、ivarに格納するCGRectを呼び出し元に既に要求しています。 loadViewメソッドが呼び出されたときに、このivarを使用してビューを作成します。

ここに行く良い方法は何ですか?ビューのフレームを2回設定する(CGRectZeroで初期化し、後で設定する)か、UIViewControllerにCGRectを使用して新しい初期化メソッドを与える(したがって、フレームプロパティを与える)か?それとも私は何かが足りないのですか、他の可能性はありますか?

28
drvdijk

指定された初期化子を使用しないでくださいする必要があります[[UIView alloc] init]のようにinitを使用するだけです。指定された初期化子は、サブクラスの初期化子から使用する必要があります。

一方、フレームを2回設定しても、それほど害はありません。 setFrame:で多くのタスクを実行するのは珍しいことです。レイアウトは通常layoutSubviewsで実行され、1回だけ実行されます。

8
Nikolai Ruhe

使用可能な画面スペースの境界を計算することをお勧めします(ナビゲーションバー、タブバー、ステータスバーなどの他のビューの存在によって異なります)。これらの境界は、loadViewの[[UIView alloc] initWithFrame:]のフレームパラメータに使用できます。

これが必要な場合は、ここでの私の答えが役立つかもしれません: loadViewで正しいサイズを決定してください

0
Tafkadasoh

私は現在、UIViewControllerからサブクラス化して汎用コンポーネントを作成した後、同じことを達成しようとしていますが、非常に奇妙なことに気づきました。

UIViewControllerには、オーバーライドできる「loadView」メソッドがあります(ドキュメントを引用)「これは、サブクラスがカスタムビュー階層を作成する場所です」。

そこで、デフォルトのフレームサイズを使用して画面を合成し、ビュー階層を作成します(loadViewが呼び出されたときに表示するフレームがわからない可能性があるため)。

しかし、どの呼び出しでフレームサイズを正しく設定しますか?別名:ビューコントローラーは、ビューの実際のサイズをいつ認識しますか?

ViewControllerを作成するオブジェクトが呼び出す必要があるViewControllerサブクラスに「setFrame」を作成する必要がありますか?それは奇妙に思えます。

drvdijk:問題の解決策はありましたか?

編集:UIViewControllerドキュメントでこのメモを見つけました:注:ウィンドウの一部、つまりアプリケーションコンテンツの長方形で定義された領域の一部のみを埋めるビューを管理するためにビューコントローラーを使用しないでください。複数の小さなビューで構成されるインターフェースが必要な場合は、それらすべてを単一のルートビューに埋め込み、ViewControllerでそのビューを管理します。

したがって、UIViewControllerのメインビューは常に全画面表示になっているようです。限目。

ただし、カスタムUITabBarViewControllerを作成しようとしているので(青いグラデーションではなく、タブバーにカスタム画像を表示できるようにするため)、問題が発生します。tabBarViewControllerは、ウィンドウの一部にのみサブビューコントローラーを表示する必要があります。 ..

0
Ben G