Étant donné que la question que j'ai posée a été vue à plusieurs reprises, j'en fournirai une réponse détaillée. N'hésitez pas à le modifier si vous souhaitez ajouter un contenu plus correct.
Tout d'abord un récapitulatif de la question: cadre, limites et centre et leurs relations.
Le cadre La vue frame
( CGRect
) est la position de son rectangle dans le superview
système de coordonnées de. Par défaut, il commence en haut à gauche.
Limites Une vue bounds
( CGRect
) exprime un rectangle de vue dans son propre système de coordonnées.
Le centre A center
est CGPoint
exprimé en termes de superview
système de coordonnées et détermine la position du point central exact de la vue.
Tirées de la position UIView +, voici les relations (elles ne fonctionnent pas dans le code car ce sont des équations informelles) entre les propriétés précédentes:
REMARQUE: ces relations ne s'appliquent pas si les vues sont pivotées. Pour plus d'informations, je vous suggère de jeter un œil à l'image suivante tirée du tiroir de cuisine basé sur le cours Stanford CS193p . Les crédits vont à @Rhubarb .
L'utilisation de frame
vous permet de repositionner et / ou de redimensionner une vue dans sa superview
. Peut généralement être utilisé à partir de superview
, par exemple, lorsque vous créez une sous-vue spécifique. Par exemple:
// 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];
Lorsque vous avez besoin des coordonnées pour dessiner à l'intérieur d'un view
fichier auquel vous vous référez habituellement bounds
. Un exemple typique pourrait être de dessiner dans une view
sous-vue en tant qu'encart de la première. Pour dessiner la sous-vue, vous devez connaître la vue bounds
d'ensemble. Par exemple:
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];
Différents comportements se produisent lorsque vous modifiez la bounds
vue. Par exemple, si vous modifiez le bounds
size
, les frame
modifications (et vice versa). Le changement se produit autour center
de la vue. Utilisez le code ci-dessous et voyez ce qui se passe:
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));
De plus, si vous changez, bounds
origin
vous modifiez le origin
système de coordonnées interne. Par défaut, le origin
est à (0.0, 0.0)
(coin supérieur gauche). Par exemple, si vous modifiez le origin
pourview1
vous pouvez voir (commentez le code précédent si vous le souhaitez) que maintenant le coin supérieur gauche pour view2
touche view1
celui. La motivation est assez simple. Vous dites view1
que son coin supérieur gauche est maintenant à la position , (20.0, 20.0)
mais depuis view2
de » frame
origin
les départs à partir (20.0, 20.0)
, ils coïncident.
CGRect frame = view1.bounds;
frame.origin.x += 20.0f;
frame.origin.y += 20.0f;
view1.bounds = frame;
Le origin
représente la view
position de l 'au sein de son superview
mais décrit la position dubounds
centre.
Enfin, bounds
et origin
ne sont pas des concepts liés. Les deux permettent de dériver la frame
vue (voir les équations précédentes).
Étude de cas de View1
Voici ce qui se passe lors de l'utilisation de l'extrait de code suivant.
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]));
L'image relative.
C'est ce qui se passe à la place si je change les [self view]
limites comme suit.
// previous code here...
CGRect rect = [[self view] bounds];
rect.origin.x += 30.0f;
rect.origin.y += 20.0f;
[[self view] setBounds:rect];
L'image relative.
Ici tu dis à [self view]
que son coin supérieur gauche est maintenant à la position (30.0, 20.0) mais puisque view1
l'origine du cadre commence à (30.0, 20.0), ils coïncideront.
Références supplémentaires (à mettre à jour avec d'autres références si vous le souhaitez)
À propos clipsToBounds
(source doc Apple)
Si vous définissez cette valeur sur OUI, les sous-vues sont tronquées aux limites du récepteur. Si elle est définie sur NO, les sous-vues dont les images s'étendent au-delà des limites visibles du récepteur ne sont pas écrêtées. La valeur par défaut est NO.
En d'autres termes, si une vue frame
est (0, 0, 100, 100)
et sa sous-vue (90, 90, 30, 30)
, vous ne verrez qu'une partie de cette sous-vue. Ce dernier ne dépassera pas les limites de la vue parent.
masksToBounds
est équivalent à clipsToBounds
. A la place de a UIView
, cette propriété est appliquée à a CALayer
. Sous le capot, les clipsToBounds
appels masksToBounds
. Pour d'autres références, jetez un œil à Comment est la relation entre les clipsToBounds d'UIView et les masquesToBounds de CALayer? .