Da die von mir gestellte Frage schon oft gesehen wurde, werde ich eine detaillierte Antwort darauf geben. Sie können es jederzeit ändern, wenn Sie korrekteren Inhalt hinzufügen möchten.
Zunächst eine Zusammenfassung der Frage: Rahmen, Grenzen und Zentrum und ihre Beziehungen.
Rahmen Die Ansicht frame
( CGRect
) einer Ansicht ist die Position ihres Rechtecks im superview
Koordinatensystem des Ansichts . Standardmäßig beginnt es oben links.
Grenzen Eine Ansicht bounds
( CGRect
) drückt ein Ansichtsrechteck in einem eigenen Koordinatensystem aus.
Mittelpunkt A center
wird CGPoint
in Form des superview
Koordinatensystems ausgedrückt und bestimmt die Position des exakten Mittelpunkts der Ansicht.
Aus UIView + -Position entnommen sind dies die Beziehungen (sie funktionieren nicht im Code, da es sich um informelle Gleichungen handelt) zwischen den vorherigen Eigenschaften:
HINWEIS: Diese Beziehungen gelten nicht, wenn Ansichten gedreht werden. Für weitere Informationen schlage ich vor, dass Sie sich das folgende Bild aus The Kitchen Drawer ansehen, das auf dem Stanford CS193p- Kurs basiert . Credits gehen an @Rhubarb .
Mit der frame
Option können Sie eine Ansicht innerhalb der Ansicht neu positionieren und / oder deren Größe ändern superview
. Kann normalerweise von a verwendet werden superview
, wenn Sie beispielsweise eine bestimmte Unteransicht erstellen. Zum Beispiel:
// 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];
Wenn Sie die Koordinaten zum Zeichnen in einem benötigen, view
beziehen Sie sich normalerweise auf bounds
. Ein typisches Beispiel könnte sein, in view
einer Unteransicht als Einschub der ersten zu zeichnen . Das Zeichnen der Unteransicht erfordert die Kenntnis bounds
der Übersicht. Zum Beispiel:
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];
Unterschiedliche Verhaltensweisen treten auf, wenn Sie die bounds
Ansicht ändern . Wenn Sie beispielsweise das ändern bounds
size
, ändern sich die frame
Änderungen (und umgekehrt). Die Änderung erfolgt um center
die Ansicht herum . Verwenden Sie den folgenden Code und sehen Sie, was passiert:
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));
Wenn Sie sich ändern, ändern bounds
origin
Sie außerdem das origin
interne Koordinatensystem. Standardmäßig origin
ist das bei (0.0, 0.0)
(obere linke Ecke). Wenn Sie beispielsweise das origin
für ändern view1
, können Sie sehen (kommentieren Sie den vorherigen Code, wenn Sie möchten), dass jetzt die obere linke Ecke für view2
den view1
einen berührt . Die Motivation ist ganz einfach. Sie sagen, view1
dass sich die obere linke Ecke jetzt an der Position befindet, (20.0, 20.0)
aber da view2
die von frame
origin
beginnt (20.0, 20.0)
, werden sie zusammenfallen.
CGRect frame = view1.bounds;
frame.origin.x += 20.0f;
frame.origin.y += 20.0f;
view1.bounds = frame;
Das origin
repräsentiert die view
Position des 's innerhalb seiner superview
, beschreibt aber die Position des bounds
Zentrums.
Schließlich bounds
und origin
sind keine verwandten Konzepte. Beide erlauben es, das frame
einer Ansicht abzuleiten (siehe vorherige Gleichungen).
Die Fallstudie von View1
Folgendes passiert, wenn das folgende Snippet verwendet wird.
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]));
Das relative Bild.
Dies passiert stattdessen, wenn ich die [self view]
Grenzen wie folgt ändere .
// previous code here...
CGRect rect = [[self view] bounds];
rect.origin.x += 30.0f;
rect.origin.y += 20.0f;
[[self view] setBounds:rect];
Das relative Bild.
Hier sagst du, [self view]
dass sich seine obere linke Ecke jetzt an der Position (30.0, 20.0) befindet, aber da view1
der Frame-Ursprung von (30.0, 20.0) beginnt, fallen sie zusammen.
Zusätzliche Referenzen (zum Aktualisieren mit anderen Referenzen, wenn Sie möchten)
Über clipsToBounds
(Quelle Apple Doc)
Wenn Sie diesen Wert auf YES setzen, werden Unteransichten an die Grenzen des Empfängers gekürzt. Bei der Einstellung NO werden Unteransichten, deren Frames über die sichtbaren Grenzen des Empfängers hinausragen, nicht abgeschnitten. Der Standardwert ist NO.
Mit anderen Worten, wenn eine Ansicht frame
ist (0, 0, 100, 100)
und ihre Unteransicht ist (90, 90, 30, 30)
, sehen Sie nur einen Teil dieser Unteransicht. Letzteres überschreitet nicht die Grenzen der übergeordneten Ansicht.
masksToBounds
ist äquivalent zu clipsToBounds
. Anstelle von a UIView
wird diese Eigenschaft auf a angewendet CALayer
. Unter der Haube clipsToBounds
ruft masksToBounds
. Weitere Referenzen finden Sie unter Wie ist die Beziehung zwischen den ClipsToBounds von UIView und den MaskenToBounds von CALayer? .