Поскольку вопрос, который я задал, видели много раз, я дам на него подробный ответ. Не стесняйтесь изменять его, если хотите добавить более правильный контент.
Сначала резюмируем вопрос: фрейм, границы, центр и их отношения.
Рамка frame
(CGRect
) представления - это положение его прямоугольника в системе координат superview
. По умолчанию он начинается в левом верхнем углу.
Границы bounds
(CGRect
) вида выражает прямоугольник вида в его собственной системе координат.
Центр center
- это CGPoint
, выраженный в системе координат superview
, и он определяет положение точной центральной точки обзора.
Взято из позиции UIView +, это отношения (они не t работают в коде, поскольку они являются неформальными уравнениями) среди предыдущих свойств:
ПРИМЕЧАНИЕ. Эти отношения не применяются, если виды повернуты. Для получения дополнительной информации я предлагаю вам взглянуть на следующее изображение, взятое из Кухонный ящик < / strong> на основе курса Stanford CS193p. Кредит предоставляется @Rhubarb.
![Рамка, границы и центр](https://i.stack.imgur.com/3jcne.jpg)
Использование 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
на view1
, вы увидите (прокомментируйте предыдущий код, если хотите), что теперь верхний левый угол для view2
соприкасается с view1
. Мотивация довольно проста. Вы говорите view1
, что его верхний левый угол сейчас находится в позиции (20.0, 20.0)
, но поскольку frame
origin
view2
начинается с (20.0, 20.0)
, они будут совпадать.
CGRect frame = view1.bounds;
frame.origin.x += 20.0f;
frame.origin.y += 20.0f;
view1.bounds = frame;
origin
представляет положение view
в его 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]));
Относительный образ.
![введите описание изображения здесь](https://i.stack.imgur.com/O59da.png)
Это вместо того, что произойдет, если я изменю [self view]
границы, как показано ниже.
// previous code here...
CGRect rect = [[self view] bounds];
rect.origin.x += 30.0f;
rect.origin.y += 20.0f;
[[self view] setBounds:rect];
Относительный образ.
![введите описание изображения здесь](https://i.stack.imgur.com/OgI77.png)
Здесь вы говорите [self view]
, что его верхний левый угол теперь находится в позиции (30.0, 20.0), но поскольку начало координат кадра view1
начинается с (30.0, 20.0), они будут совпадать.
Дополнительные ссылки (при желании можно добавить другие ссылки)
О clipsToBounds
(исходный документ Apple)
Установка этого значения в YES приводит к тому, что подпредставления будут обрезаны до границ получателя. Если установлено значение NO, подпредставления, кадры которых выходят за видимые границы приемника, не обрезаются. Значение по умолчанию - НЕТ.
Другими словами, если frame
представления - (0, 0, 100, 100)
, а его подпредставление - (90, 90, 30, 30)
, вы увидите только часть этого подпредставления. Последний не выходит за пределы родительского представления.
masksToBounds
эквивалентно clipsToBounds
. Вместо UIView
это свойство применяется к CALayer
. Под капотом clipsToBounds
звонит masksToBounds
. Дополнительные ссылки см. В Какова связь между ClipsToBounds UIView и masksToBounds CALayer?.
person
Community
schedule
01.07.2012