これらのプロパティを正しく使用する方法を知りたいです。
私の理解では、frame
作成しているビューのコンテナーから使用できます。コンテナー ビューに対するビューの位置を設定します。また、そのビューのサイズも設定します。
center
作成しているビューのコンテナーからも使用できます。このプロパティは、コンテナーに対するビューの位置を変更します。
最後に、bounds
ビュー自体を基準に、ビューの描画可能領域を変更します。
frame
との関係について、さらに詳しく教えていただけますかbounds
?clipsToBounds
とmasksToBounds
プロパティについてはどうですか?
ベストアンサー1
私が尋ねた質問は何度も見られているので、詳細な回答を提供します。より正確な内容を追加したい場合は、自由に修正してください。
まず、フレーム、境界、中心、およびそれらの関係についての質問を要約します。
フレームビューのframe
( CGRect
) は、 の座標系におけるその四角形の位置ですsuperview
。デフォルトでは左上から始まります。
境界ビューのbounds
( CGRect
) は、独自の座標系でビューの四角形を表します。
中心A はの座標系で表現されcenter
、ビューの正確な中心点の位置を決定します。CGPoint
superview
出典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
内に描画することが挙げられます。サブビューを描画するには、スーパービューの を知っている必要があります。例:view
bounds
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
変更されます。デフォルトでは、 は (左上隅)にあります。たとえば、 をに変更すると、(必要に応じて前のコードをコメントアウトしてください) の の左上隅が に接するようになります。その理由は非常に単純です。の の左上隅が の位置にあるとしますが、はから始まるため、それらは一致することになります。origin
origin
(0.0, 0.0)
origin
view1
view2
view1
view1
(20.0, 20.0)
view2
frame
origin
(20.0, 20.0)
CGRect frame = view1.bounds;
frame.origin.x += 20.0f;
frame.origin.y += 20.0f;
view1.bounds = frame;
は の 内の位置をorigin
表しますが、中心の位置を表します。view
superview
bounds
最後に、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 の関係はどうなっていますか?。