Como a pergunta que fiz foi vista muitas vezes, fornecerei uma resposta detalhada. Sinta-se à vontade para modificá-lo se desejar adicionar mais conteúdo correto.
Primeiro, uma recapitulação da questão: estrutura, limites e centro e o relacionamento deles.
Quadro A vista frame
( CGRect
) é a posição do seu retângulo no superview
sistema de coordenadas da. Por padrão, ele começa no canto superior esquerdo.
Limites As vistas bounds
( CGRect
) expressam um retângulo de vista em seu próprio sistema de coordenadas.
O centro A center
é CGPoint
expresso em termos desuperview
sistema de coordenadas do e determina a posição do ponto central exato da vista.
Retirados da posição do UIView +, esses são os relacionamentos (eles não funcionam no código, pois são equações informais) entre as propriedades anteriores:
NOTA: Esses relacionamentos não se aplicam se as vistas forem giradas. Para mais informações, sugiro que você dê uma olhada na imagem a seguir, tirada de The Kitchen Drawer, com base no curso Stanford CS193p . Os créditos vão para @Rhubarb .
Usar o frame
permite reposicionar e / ou redimensionar uma vista dentro dela superview
. Geralmente, pode ser usado a partir de superview
, por exemplo, quando você cria uma subvisão específica. Por exemplo:
// 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 você precisa das coordenadas para desenhar dentro de um, view
você costuma se referir bounds
. Um exemplo típico pode ser desenhar dentro de view
uma subvisão como uma inserção da primeira. Para desenhar a subvisão, é necessário conhecer bounds
a supervisão. Por exemplo:
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];
Comportamentos diferentes acontecem quando você altera o modo bounds
de exibição. Por exemplo, se você alterar bounds
size
, as frame
alterações (e vice-versa). A mudança acontece em torno center
da vista. Use o código abaixo e veja o que acontece:
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));
Além disso, se você alterar, bounds
origin
altere o origin
sistema de coordenadas interno. Por padrão, origin
está em (0.0, 0.0)
(canto superior esquerdo). Por exemplo, se você alterar o origin
para, view1
poderá ver (comente o código anterior, se desejar) que agora o canto superior esquerdo view2
toca no view1
. A motivação é bastante simples. Você diz para view1
que seu topo canto esquerdo agora está na posição (20.0, 20.0)
mas desde view2
's frame
origin
começa a partir (20.0, 20.0)
, eles vão coincidir.
CGRect frame = view1.bounds;
frame.origin.x += 20.0f;
frame.origin.y += 20.0f;
view1.bounds = frame;
O origin
representa a view
posição do dentro dele, superview
mas descreve a posição dobounds
centro.
Finalmente, bounds
e origin
não são conceitos relacionados. Ambos permitem derivar a frame
vista (Veja as equações anteriores).
Estudo de caso de View1
Aqui está o que acontece ao usar o seguinte snippet.
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]));
A imagem relativa.
Em vez disso, o que acontece se eu mudar os [self view]
limites da seguinte forma.
// previous code here...
CGRect rect = [[self view] bounds];
rect.origin.x += 30.0f;
rect.origin.y += 20.0f;
[[self view] setBounds:rect];
A imagem relativa.
Aqui você diz [self view]
que seu canto superior esquerdo está agora na posição (30.0, 20.0), mas como view1
a origem do quadro começa em (30.0, 20.0), eles coincidirão.
Referências adicionais (para atualizar com outras referências, se desejar)
Sobre clipsToBounds
(fonte Apple doc)
Definir esse valor como YES faz com que as subviews sejam cortadas nos limites do receptor. Se definido como NÃO, as subvisões cujos quadros ultrapassam os limites visíveis do receptor não serão cortadas. O valor padrão é não.
Em outras palavras, se uma visualização frame
é (0, 0, 100, 100)
e sua subvisão é (90, 90, 30, 30)
, você verá apenas uma parte dessa subvisualização. Este último não excederá os limites da visualização principal.
masksToBounds
é equivalente a clipsToBounds
. Em vez de a UIView
, essa propriedade é aplicada a a CALayer
. Sob o capô, clipsToBounds
chama masksToBounds
. Para referências adicionais, consulte Como está a relação entre clipsToBounds do UIView e masksToBounds do CALayer? .