質問は何度も出てきましたので、詳しくお答えします。より正確なコンテンツを追加したい場合は、自由に変更してください。
最初に質問の要約:フレーム、境界、中心およびそれらの関係。
フレーム Aビューのframe
(CGRect
)は、superview
の座標系における長方形の位置です。デフォルトでは左上から始まります。
境界ビューのbounds
(CGRect
)は、ビューの長方形を独自の座標系で表します。
中心 Aはcenter
さCGPoint
で表現superview
の座標系とそれがビューの正確な中心点の位置を決定します。
UIView +位置から取得すると、これらは前のプロパティ間の関係です(非公式の方程式であるため、コードでは機能しません)。
注:ビューが回転されている場合、これらの関係は適用されません。詳細については、以下の画像をご覧になることをお勧めしますスタンフォード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
for を変更すると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 doc)
この値をYESに設定すると、サブビューがレシーバーの境界にクリップされます。NOに設定すると、フレームがレシーバーの可視境界を超えて伸びるサブビューはクリップされません。デフォルト値はNOです。
つまり、ビューframe
がで(0, 0, 100, 100)
あり、そのサブビューが(90, 90, 30, 30)
である場合、そのサブビューの一部のみが表示されます。後者は、親ビューの境界を超えることはありません。
masksToBounds
と同等clipsToBounds
です。の代わりにUIView
、このプロパティはに適用されますCALayer
。内部では、をclipsToBounds
呼び出しますmasksToBounds
。詳細については、UIViewのclipsToBoundsとCALayerのmasksToBoundsの関係をご覧ください。。