Поскольку вопрос, который я задавал, встречался много раз, я приведу подробный ответ на него. Не стесняйтесь изменять его, если вы хотите добавить более правильный контент.
Сначала краткий обзор вопроса: рамка, границы, центр и их отношения.
Кадр Представление frame
( CGRect
) - это положение его прямоугольника вsuperview
координат России. По умолчанию он начинается слева вверху.
Границы вида bounds
(CGRect
) выражает прямоугольник представления в своей собственной системе координат.
Центрcenter
является CGPoint
выраженным в терминахsuperview
системы «s координат и определяет положение точной центральной точки зрения.
Взятые из UIView + position это отношения (они не работают в коде, поскольку они являются неформальными уравнениями) среди предыдущих свойств:
ПРИМЕЧАНИЕ. Эти отношения не применяются, если представления повернуты. Для получения дополнительной информации, я предлагаю вам взглянуть на следующее изображение, взятое из кухонного ящика на основе курса Stanford CS193p . Кредиты идут в @Rhubarb .
Использование frame
позволяет изменить положение и / или изменить размер представления в пределах его superview
. Обычно его можно использовать superview
, например, при создании определенного подпредставления. Например:
// 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];
Когда вам нужны координаты для рисования внутри, view
вы обычно ссылаетесь bounds
. Типичным примером может быть рисование внутри view
подпредставления как вставка первого. Составление подпредставления требует знания bounds
суперпредставления. Например:
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];
Различное поведение происходит, когда вы меняете bounds
представление. Например, если вы измените bounds
size
, frame
изменения (и наоборот). Изменение происходит по center
всему виду. Используйте код ниже и посмотрите, что произойдет:
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));
Кроме того, если вы измените, bounds
origin
вы измените origin
его внутреннюю систему координат. По умолчанию origin
это в (0.0, 0.0)
(верхний левый угол). Например, если вы измените « origin
for», view1
вы увидите (прокомментируйте предыдущий код, если хотите), что теперь левый верхний угол view2
касается view1
. Мотивация довольно проста. Вы говорите , view1
что его верхний левый угол в настоящее время находится в положении , (20.0, 20.0)
но так как view2
«S frame
origin
начинается с (20.0, 20.0)
, они будут совпадать.
CGRect frame = view1.bounds;
frame.origin.x += 20.0f;
frame.origin.y += 20.0f;
view1.bounds = frame;
origin
Представляет view
позицию «S в пределах его , superview
но описывает положениеbounds
центра.
Наконец, bounds
и origin
не связанные понятия. Оба позволяют получить frame
вид (см. Предыдущие уравнения).
Пример использования View1
Вот что происходит при использовании следующего фрагмента.
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]));
Относительное изображение.
Это вместо того, что произойдет, если я изменю [self view]
границы следующим образом.
// previous code here...
CGRect rect = [[self view] bounds];
rect.origin.x += 30.0f;
rect.origin.y += 20.0f;
[[self view] setBounds:rect];
Относительное изображение.
Здесь вы говорите, [self view]
что его левый верхний угол теперь находится в позиции (30.0, 20.0), но поскольку view1
начало кадра начинается с (30.0, 20.0), они будут совпадать.
Дополнительные ссылки (для обновления другими ссылками, если хотите)
О clipsToBounds
(источник Apple Doc)
Установка этого значения в YES приводит к тому, что подпредставления обрезаются до границ получателя. Если установлено значение NO, подпредставления, кадры которых выходят за пределы видимых границ приемника, не обрезаются. Значением по умолчанию является НЕТ.
Другими словами, если представление frame
есть (0, 0, 100, 100)
и его подпредставление есть (90, 90, 30, 30)
, вы увидите только часть этого подпредставления. Последнее не будет выходить за пределы родительского представления.
masksToBounds
эквивалентно clipsToBounds
. Вместо этого UIView
это свойство применяется к CALayer
. Под капотом clipsToBounds
звонит masksToBounds
. Для дальнейших ссылок взгляните на Какова связь между clipsToBounds UIView и masksToBounds CALayer? ,