321 votes

Cadre UIView, limites et centre

Je voudrais savoir comment utiliser ces propriétés dans la bonne manière.

Ce que je comprends, frame peut être utilisé à partir du conteneur de la vue, je suis en train de créer. Il définit la position de la vue par rapport au conteneur vue. Il définit également la taille de ce point de vue.

Aussi center peut être utilisé à partir du conteneur de la vue que je suis en train de créer. Cette propriété modifie la position de la vue par rapport à son conteneur.

Enfin, bounds est par rapport à la vue elle-même. Il modifie le drawable de la zone pour l'afficher.

Pouvez-vous donner plus d'informations à propos de la relation entre frame et bounds? Quel est le clipsToBounds et masksToBounds propriétés?

579voto

flexaddicted Points 16208

Car la question que j'avais posée a été vu à plusieurs reprises, je vais donner une réponse détaillée. N'hésitez pas à modifier si vous voulez ajouter plus de contenu approprié.

D'abord un récapitulatif sur la question: le cadre, de limites et d'un centre et de leurs relations.

Cadre en vue de l' frame (CGRect) est la position de son rectangle en superview's système de coordonnées. Par défaut, il commence en haut à gauche.

Les limites de vue de l' bounds (CGRect) exprime un point de vue rectangle dans son propre système de coordonnées.

Centre Une center est CGPoint exprimée en superview's système de coordonnées, et elle détermine la position exacte du centre de la vue.

Prises de UIView + position de ces sont les liens (ils ne fonctionnent pas dans le code, car ils sont des équations) parmi les propriétés précédentes:

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

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

  • frame.size = bounds.size

REMARQUE: Ces relations ne s'appliquent pas si les vues sont en rotation. Pour de plus amples informations, je vous suggère de prendre un coup d'oeil à l'image ci-dessous prise à partir Du Tiroir de la Cuisine basée sur Stanford CS193p cours. Crédits va à @Rhubarbe.

Frame, bounds and center

À l'aide de l' frame permet de repositionner et/ou redimensionner une vue à l'intérieur de ses superview. Généralement peut être utilisé à partir d'un superview, par exemple, lorsque vous créez un spécifique de la sous-vue. 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 de dessin à l'intérieur d'un view vous concernent habituellement bounds. Un exemple typique pourrait être à dessiner dans un view d'une sous-vue comme un encart de la première. Le dessin de la sous-vue nécessite de connaître le bounds de la superview. 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];

Des comportements différents de se produire lorsque vous modifiez l' bounds d'un point de vue. Par exemple, si vous modifiez l' bounds size, frame change (et vice versa). Le changement qui se passe autour de l' center de la vue. Utilisez le code ci-dessous et voir 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));

En outre, si vous modifiez bounds origin vous modifiez l' origin de son système de coordonnées internes. Par défaut, l' origin est (0.0, 0.0) (coin supérieur gauche). Par exemple, si vous modifiez l' origin pour view1 vous pouvez le voir (commentaire le code précédent si vous voulez) qui maintenant le coin en haut à gauche pour view2 touche l' view1 . La motivation est assez simple. Vous vous dites view1 que son coin supérieur gauche est maintenant à la position (20.0, 20.0) mais depuis view2s' frame origin commence à partir de (20.0, 20.0), ils coïncident.

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

L' origin représente l' view'à la position à l'intérieur de ses superview mais décrit la position de l' bounds center.

Enfin, bounds et origin ne sont pas des concepts connexes. Les deux permettent de dériver de l' frame d'un point de vue (Voir équations précédentes).

Vue1 de l'étude de cas

Voici ce qui se passe lors de l'utilisation de l'extrait 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]));

Le parent de l'image.

enter image description here

Ceci à la place qu'advient-il si je change d' [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];

Le parent de l'image.

enter image description here

Ici, vous dites à l' [self view] que son coin supérieur gauche est maintenant à la position (30.0, 20.0), mais depuis view1'image d'origine commence à partir (30.0, 20.0), ils coïncident.

Références supplémentaires (pour la mise à jour avec d'autres références si vous le souhaitez)

À propos de clipsToBounds (source Apple doc)

La définition de cette valeur YES causes sous-vues à être clipsé sur les limites du récepteur. Si NON, les sous-vues dont les images s'étendre au-delà de la visible limites du récepteur sont pas coupés. La valeur par défaut est PAS de.

En d'autres termes, si une vue de l' frame est (0, 0, 100, 100) et de ses sous-vue est - (90, 90, 30, 30), vous ne voyez qu'une partie de la sous-vue. Le dernier de ne pas dépasser les limites de la vue parent.

masksToBounds est équivalent à clipsToBounds. Au lieu d'un UIView, cette propriété est appliquée à un CALayer. Sous le capot, clipsToBounds des appels masksToBounds. Pour plus de références de prendre un coup d'oeil à Comment la relation entre UIView de clipsToBounds et CALayer de masksToBounds?.

89voto

Erben Mo Points 1058

J'ai trouvé cette image très utile pour comprendre le cadre, les limites, etc.

entrez la description de l'image ici

Notez également que frame.size != bounds.size lorsque l'image est pivotée.

8voto

Saheb Singh Points 111
  • La propriété frame contient le rectangle du cadre, qui spécifie la taille et l'emplacement de la vue dans le système de coordonnées de sa vue d'ensemble.
  • La propriété bounds contient le rectangle bounds, qui spécifie la taille de la vue (et son origine de contenu) dans le propre système de coordonnées local de la vue.
  • La propriété center contient le point central connu de la vue dans le système de coordonnées de la vue d'ensemble.

3voto

coolbeet Points 65

Je pense que si vous pensez que du point de CALayer, tout est plus clair.

Cadre n'est pas vraiment une propriété distincte de la vue ou de la couche, c'est une propriété virtuelle, calculé à partir de la limite, de la position(UIView's centre), et de les transformer.

Donc, fondamentalement, la façon dont la couche/afficher les mises en page est vraiment décidé par ces trois biens(et anchorPoint), et l'une de ces trois biens ne changera pas de toute autre propriété, comme l'évolution de transformation ne change pas de limites.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X