UIView のフレーム、境界、中心 質問する

UIView のフレーム、境界、中心 質問する

これらのプロパティを正しく使用する方法を知りたいです。

私の理解では、frame作成しているビューのコンテナーから使用できます。コンテナー ビューに対するビューの位置を設定します。また、そのビューのサイズも設定します。

center作成しているビューのコンテナーからも使用できます。このプロパティは、コンテナーに対するビューの位置を変更します。

最後に、boundsビュー自体を基準に、ビューの描画可能領域を変更します。

frameとの関係について、さらに詳しく教えていただけますかbounds?clipsToBoundsmasksToBoundsプロパティについてはどうですか?

ベストアンサー1

私が尋ねた質問は何度も見られているので、詳細な回答を提供します。より正確な内容を追加したい場合は、自由に修正してください。

まず、フレーム、境界、中心、およびそれらの関係についての質問を要約します。

フレームビューのframe( CGRect) は、 の座標系におけるその四角形の位置ですsuperview。デフォルトでは左上から始まります。

境界ビューのbounds( CGRect) は、独自の座標系でビューの四角形を表します。

中心A はの座標系で表現されcenter、ビューの正確な中心点の位置を決定します。CGPointsuperview

出典UIView + 位置これらは、前のプロパティ間の関係です (非公式の方程式であるため、コードでは機能しません)。

  • frame.origin = center - (bounds.size / 2.0)

  • center = frame.origin + (bounds.size / 2.0)

  • frame.size = bounds.size

注:これらの関係は、ビューが回転している場合は適用されません。詳細については、次の画像をご覧ください。キッチンの引き出しに基づくスタンフォード CS193pもちろん。クレジットは@Rhubarbに帰属します。

フレーム、境界、中心

を使用するframeと、 内のビューの位置やサイズを変更できますsuperview。通常は、特定のサブビューを作成するときなど、 から を使用できますsuperview。例:

// view1 will be positioned at x = 30, y = 20 starting the top left corner of [self view]
// [self view] could be the view managed by a UIViewController
UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(30.0f, 20.0f, 400.0f, 400.0f)];    
view1.backgroundColor = [UIColor redColor];

[[self view] addSubview:view1];

内部に描画するための座標が必要な場合は、view通常 を参照します。典型的な例としては、サブビューを最初のビューのインセットとしてbounds内に描画することが挙げられます。サブビューを描画するには、スーパービューの を知っている必要があります。例:viewbounds

UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(50.0f, 50.0f, 400.0f, 400.0f)];    
view1.backgroundColor = [UIColor redColor];

UIView* view2 = [[UIView alloc] initWithFrame:CGRectInset(view1.bounds, 20.0f, 20.0f)];    
view2.backgroundColor = [UIColor yellowColor];

[view1 addSubview:view2];

ビューのを変更すると、さまざまな動作が発生しますbounds。たとえば、 を変更するとbounds size、 がframe変更されます (逆も同様)。変更は、centerビューの の周囲で発生します。以下のコードを使用して、何が起こるかを確認します。

NSLog(@"Old Frame %@", NSStringFromCGRect(view2.frame));
NSLog(@"Old Center %@", NSStringFromCGPoint(view2.center));    

CGRect frame = view2.bounds;
frame.size.height += 20.0f;
frame.size.width += 20.0f;
view2.bounds = frame;

NSLog(@"New Frame %@", NSStringFromCGRect(view2.frame));
NSLog(@"New Center %@", NSStringFromCGPoint(view2.center));

さらに、 を変更すると、その内部座標系の もbounds origin変更されます。デフォルトでは、 は (左上隅)にあります。たとえば、 をに変更すると、(必要に応じて前のコードをコメントアウトしてください) の の左上隅が に接するようになります。その理由は非常に単純です。の の左上隅が の位置にあるとしますが、はから始まるため、それらは一致することになります。originorigin(0.0, 0.0)originview1view2view1view1(20.0, 20.0)view2frame origin(20.0, 20.0)

CGRect frame = view1.bounds;
frame.origin.x += 20.0f;
frame.origin.y += 20.0f;
view1.bounds = frame; 

は の 内の位置をorigin表しますが、中心の位置を表します。viewsuperviewbounds

最後に、boundsと はorigin関連した概念ではありません。 どちらも、frameビューの を導出することを可能にします (前の式を参照)。

View1のケーススタディ

次のスニペットを使用すると、次のことが起こります。

UIView* view1 = [[UIView alloc] initWithFrame:CGRectMake(30.0f, 20.0f, 400.0f, 400.0f)];
view1.backgroundColor = [UIColor redColor];

[[self view] addSubview:view1];

NSLog(@"view1's frame is: %@", NSStringFromCGRect([view1 frame]));
NSLog(@"view1's bounds is: %@", NSStringFromCGRect([view1 bounds]));
NSLog(@"view1's center is: %@", NSStringFromCGPoint([view1 center]));

相対的なイメージ。

ここに画像の説明を入力してください

代わりに、[self view]次のように境界を変更するとどうなるでしょうか。

// previous code here...
CGRect rect = [[self view] bounds];
rect.origin.x += 30.0f;
rect.origin.y += 20.0f;
[[self view] setBounds:rect];

相対的なイメージ。

ここに画像の説明を入力してください

[self view]ここでは、 の左上隅が現在 (30.0, 20.0) の位置にあると述べていますが、view1のフレームの原点は (30.0, 20.0) から始まるため、それらは一致することになります。

追加の参考文献(必要に応じて他の参考文献で更新します)

概要clipsToBounds(ソース Apple ドキュメント)

この値を YES に設定すると、サブビューはレシーバーの境界にクリップされます。NO に設定すると、フレームがレシーバーの表示境界を超えるサブビューはクリップされません。デフォルト値は NO です。

つまり、ビューのframeが で(0, 0, 100, 100)、そのサブビューが の場合(90, 90, 30, 30)、そのサブビューの一部のみが表示されます。後者は親ビューの境界を超えることはありません。

masksToBoundsは と同等ですclipsToBounds。 の代わりにUIView、このプロパティは に適用されますCALayer。 内部的にclipsToBoundsは を呼び出しますmasksToBounds。 詳細については、 を参照してください。UIView の clipsToBounds と CALayer の masksToBounds の関係はどうなっていますか?

おすすめ記事