Poiché la domanda che ho posto è stata vista molte volte, fornirò una risposta dettagliata. Sentiti libero di modificarlo se vuoi aggiungere altro contenuto corretto.
Innanzitutto un riassunto della domanda: cornice, limiti e centro e le loro relazioni.
Frame Una vista frame
( CGRect
) è la posizione del suo rettangolo nel superview
sistema di coordinate. Di default inizia in alto a sinistra.
Limiti Una vista bounds
( CGRect
) esprime un rettangolo vista nel proprio sistema di coordinate.
Il centro A center
è CGPoint
espresso in termini di superview
sistema di coordinate del e determina la posizione del punto centrale esatto della vista.
Tratte da UIView + position, queste sono le relazioni (non funzionano nel codice poiché sono equazioni informali) tra le proprietà precedenti:
NOTA: queste relazioni non si applicano se le viste sono ruotate. Per ulteriori informazioni, ti suggerirò di dare un'occhiata alla seguente immagine tratta da The Kitchen Drawer basata sul corso Stanford CS193p . I crediti vanno a @Rhubarb .
L'uso di frame
consente di riposizionare e / o ridimensionare una vista al suo interno superview
. Di solito può essere utilizzato da un superview
, ad esempio, quando si crea una vista secondaria specifica. Per esempio:
// 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];
Quando hai bisogno delle coordinate per disegnare all'interno di una a view
cui di solito ti riferisci bounds
. Un esempio tipico potrebbe essere quello di disegnare all'interno di view
una sottoview come un inserto del primo. Disegnare la sottoview richiede di conoscere bounds
la superview. Per esempio:
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];
Si verificano comportamenti diversi quando si cambia la bounds
vista. Ad esempio, se si cambiano le bounds
size
, le frame
modifiche (e viceversa). Il cambiamento avviene attorno center
alla vista. Usa il codice qui sotto e guarda cosa succede:
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));
Inoltre, se si cambia, bounds
origin
si modifica il origin
relativo sistema di coordinate interno. Di default origin
è a (0.0, 0.0)
(angolo in alto a sinistra). Ad esempio, se cambi il origin
per view1
puoi vedere (commenta il codice precedente se vuoi) che ora l'angolo in alto a sinistra view2
tocca view1
quello. La motivazione è abbastanza semplice. Tu dici a view1
che il suo angolo in alto a sinistra è ora nella posizione (20.0, 20.0)
, ma dal momento che view2
's frame
origin
parte da (20.0, 20.0)
, essi coincidono.
CGRect frame = view1.bounds;
frame.origin.x += 20.0f;
frame.origin.y += 20.0f;
view1.bounds = frame;
Il origin
rappresenta la view
posizione del suo superview
ma descrive la posizione delbounds
centro.
Infine, bounds
e origin
non sono concetti correlati. Entrambi consentono di derivare la frame
vista (Vedi equazioni precedenti).
Caso di studio di View1
Ecco cosa succede quando si utilizza il seguente frammento.
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'immagine relativa.
Questo invece cosa succede se cambio [self view]
limiti come il seguente.
// previous code here...
CGRect rect = [[self view] bounds];
rect.origin.x += 30.0f;
rect.origin.y += 20.0f;
[[self view] setBounds:rect];
L'immagine relativa.
Qui dici [self view]
che il suo angolo in alto a sinistra ora è nella posizione (30.0, 20.0) ma poiché view1
l'origine del frame inizia da (30.0, 20.0), coincideranno.
Riferimenti aggiuntivi (da aggiornare con altri riferimenti se lo si desidera)
Informazioni clipsToBounds
(fonte Apple doc)
Impostando questo valore su SÌ, i sottoview vengono ritagliati ai limiti del ricevitore. Se impostato su NO, le visualizzazioni secondarie i cui frame si estendono oltre i limiti visibili del ricevitore non vengono ritagliate. Il valore predefinito è no.
In altre parole, se la vista frame
è (0, 0, 100, 100)
e la sua vista secondaria è (90, 90, 30, 30)
, vedrai solo una parte di quella vista secondaria. Quest'ultimo non supererà i limiti della vista padre.
masksToBounds
è equivalente a clipsToBounds
. Invece a a UIView
, questa proprietà viene applicata a CALayer
. Sotto il cofano, clipsToBounds
chiama masksToBounds
. Per ulteriori riferimenti, dai un'occhiata a Come è la relazione tra i clip di UIViewToBounds e le maschere di CALayerToBounds? .