Como la pregunta que hice se ha visto muchas veces, proporcionaré una respuesta detallada. Siéntase libre de modificarlo si desea agregar más contenido correcto.
Primero un resumen de la pregunta: marco, límites y centro y sus relaciones.
El marco de una vista frame
( CGRect
) es la posición de su rectángulo en el superview
sistema de coordenadas. Por defecto comienza en la esquina superior izquierda.
Límites Una vista bounds
( CGRect
) expresa un rectángulo de vista en su propio sistema de coordenadas.
El Centro A center
se CGPoint
expresa en términos del superview
sistema de coordenadas del 's y determina la posición del punto central exacto de la vista.
Tomados de la posición UIView +, estas son las relaciones (no funcionan en código ya que son ecuaciones informales) entre las propiedades anteriores:
NOTA: Estas relaciones no se aplican si las vistas se giran. Para más información, le sugiero que eche un vistazo a la siguiente imagen tomada de The Kitchen Drawer basada en el curso Stanford CS193p . Los créditos van a @Rhubarb .
El uso de le frame
permite reposicionar y / o cambiar el tamaño de una vista dentro de ella superview
. Por lo general, se puede usar desde superview
, por ejemplo, cuando crea una subvista específica. Por ejemplo:
// 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];
Cuando necesita las coordenadas para dibujar dentro de un view
, generalmente se refiere bounds
. Un ejemplo típico podría ser dibujar dentro de view
una subvista como una inserción de la primera. Dibujar la subvista requiere conocer la bounds
de la supervista. Por ejemplo:
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];
Se producen diferentes comportamientos cuando cambia la bounds
vista. Por ejemplo, si cambia el bounds
size
, los frame
cambios (y viceversa). El cambio ocurre alrededor center
de la vista. Use el código a continuación y vea qué sucede:
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));
Además, si cambia bounds
origin
, cambia el origin
de su sistema de coordenadas interno. Por defecto, origin
está en (0.0, 0.0)
(esquina superior izquierda). Por ejemplo, si cambia el origin
para view1
, puede ver (comente el código anterior si lo desea) que ahora la esquina superior izquierda view2
toca el view1
. La motivación es bastante simple. Usted dice a view1
que su esquina superior izquierda ahora está en la posición (20.0, 20.0)
pero ya que view2
's frame
origin
se inicia a partir (20.0, 20.0)
, ellos coinciden.
CGRect frame = view1.bounds;
frame.origin.x += 20.0f;
frame.origin.y += 20.0f;
view1.bounds = frame;
El origin
representa la view
posición del 's dentro de su superview
pero describe la posición delbounds
centro.
Finalmente, bounds
y origin
no son conceptos relacionados. Ambos permiten derivar el frame
de una vista (Ver ecuaciones anteriores).
Estudio de caso de View1
Esto es lo que sucede cuando se usa el siguiente fragmento.
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]));
La imagen relativa.
Esto, en cambio, es lo que sucede si cambio [self view]
límites como el siguiente.
// previous code here...
CGRect rect = [[self view] bounds];
rect.origin.x += 30.0f;
rect.origin.y += 20.0f;
[[self view] setBounds:rect];
La imagen relativa.
Aquí dices [self view]
que su esquina superior izquierda ahora está en la posición (30.0, 20.0) pero desdeview1
el origen del cuadro comienza desde (30.0, 20.0), coincidirán.
Referencias adicionales (para actualizar con otras referencias si lo desea)
Acerca de clipsToBounds
(fuente de Apple doc)
Establecer este valor en SÍ hace que las subvistas se recorten en los límites del receptor. Si se establece en NO, las subvistas cuyos marcos se extienden más allá de los límites visibles del receptor no se recortan. El valor predeterminado es no.
En otras palabras, si una vista frame
es (0, 0, 100, 100)
y su subvista es (90, 90, 30, 30)
, solo verá una parte de esa subvista. Este último no excederá los límites de la vista principal.
masksToBounds
es equivalente a clipsToBounds
. En lugar de a UIView
, esta propiedad se aplica a a CALayer
. Debajo del capó, clipsToBounds
llamadas masksToBounds
. Para más referencias eche un vistazo a ¿Cómo es la relación entre los clipsToBounds de UIView y las máscarasToBounds de CALayer? .