Рамка UIView, границы и центр
Я хотел бы знать, как правильно использовать эти свойства.
как я понимаю, frame
можно использовать из контейнера представления, которое я создаю.
Он устанавливает положение представления относительно представления контейнера. Он также устанавливает размер этого представления.
и center
можно использовать из контейнера представления, которое я создаю. Это свойство изменяет положение представления относительно его контейнера.
наконец, bounds
относительно представления себя. Он изменяет область рисования для вида.
можете ли вы дать больше информации о взаимоотношениях между frame
и bounds
? А как же clipsToBounds
и masksToBounds
свойства?
7 ответов:
поскольку вопрос, который я задал, был замечен много раз, я дам подробный ответ на него. Не стесняйтесь изменять его, если вы хотите добавить более правильный контент.
сначала резюме по вопросу: фрейм, границы и центр и их отношения.
рама вида
frame
(CGRect
) - это положение его прямоугольника вsuperview
система координат. По умолчанию он начинается в левом верхнем углу.границы A вид
bounds
(CGRect
) выражает прямоугольник вида в его собственной системе координат.центр A
center
этоCGPoint
выражается в терминахsuperview
система координат и она определяет положение точной центральной точки зрения.принято от UIView + position это отношения (они не работают в коде, так как они являются неформальными уравнениями) среди предыдущих свойства:
frame.origin = center - (bounds.size / 2.0)
center = frame.origin + (bounds.size / 2.0)
frame.size = bounds.size
Примечание: эти отношения не применяются, если представления вращаются. Для получения дополнительной информации, я предлагаю вам взглянуть на следующее Изображение взято из На Кухне на основе 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
наview1
вы можете увидеть (прокомментируйте предыдущий код, если хотите), что теперь верхний левый угол дляview2
умиляетview1
один. Мотивация довольно проста. Ты говоришьview1
что его верхний левый угол теперь находится в положении(20.0, 20.0)
но с тех порview2
' sframe
origin
начинается с(20.0, 20.0)
они будут совпадать.CGRect frame = view1.bounds; frame.origin.x += 20.0f; frame.origin.y += 20.0f; view1.bounds = frame;
The
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 приводит к тому, что подвиды будут обрезаны до границ из приемника. Если задано значение нет, подвиды, фреймы которых выходят за пределы видимые границы приемника не обрезаются. Значение по умолчанию НЕТ.
другими словами, если вид
frame
и(0, 0, 100, 100)
и его подвидом является(90, 90, 30, 30)
, вы увидите только часть этого подвида. Этот последний не будет выходить за пределы родительского представления.
masksToBounds
эквивалентноclipsToBounds
. Вместо этого кUIView
это свойство применяется кCALayer
. Под капотом,clipsToBounds
звонкиmasksToBounds
. Для дальнейших ссылок взгляните на каково отношение между clipsToBounds UIView и masksToBounds CALayer?.
этот вопрос уже есть хороший ответ, но я хочу дополнить его еще несколько фотографий. мой полный ответ здесь.
, чтобы помочь мне вспомнить рама, Я думаю о рама для картины на стене. Так же, как изображение может быть перемещено в любом месте на стене, система координат кадра вида является супервизором. (стена=супервизор, рамка=вид)
, чтобы помочь мне вспомнить границы, Я думаю о границы баскетбольной площадки. Баскетбол находится где-то внутри площадки, так же как система координат границ вида находится внутри самого вида. (корт=вид, баскетбол / игроки=содержание внутри вида)
как рама, вид.центр также находится в координатах супервизора.
рамка против границ-Пример 1
желтый прямоугольник представляет собой рамку вида. Зеленый прямоугольник представляет границы представления. Красная точка в обоих изображениях представляет собой начало кадра или границы в их системах координат.
Frame origin = (0, 0) width = 80 height = 130 Bounds origin = (0, 0) width = 80 height = 130
Пример 2
Frame origin = (40, 60) // That is, x=40 and y=60 width = 80 height = 130 Bounds origin = (0, 0) width = 80 height = 130
Пример 3
Frame origin = (20, 52) // These are just rough estimates. width = 118 height = 187 Bounds origin = (0, 0) width = 80 height = 130
Пример 4
это то же самое, что и в Примере 2, за исключением того, что на этот раз все содержимое представления отображается так, как оно выглядело бы, если бы оно не было обрезано до границ вид.
Frame origin = (40, 60) width = 80 height = 130 Bounds origin = (0, 0) width = 80 height = 130
Пример 5
Frame origin = (40, 60) width = 80 height = 130 Bounds origin = (280, 70) width = 80 height = 130
опять же, см. здесь для моего ответа с более подробной информацией.
Я нашел это изображение наиболее полезным для понимания рамки, границы и т. д.
Также обратите внимание, что
frame.size != bounds.size
при повороте изображения.
- свойство frame содержит прямоугольник frame, который определяет размер и расположение вида в системе координат его супервизора.
- свойство bounds содержит прямоугольник bounds, который определяет размер представления (и источник его содержимого) в собственной локальной системе координат представления.
- свойство center содержит известную центральную точку представления в системе координат супервизора.
Я думаю, если вы думаете, что это с точки зрения
CALayer
, все более ясно.Frame на самом деле не является отдельным свойством вида или слоя вообще, это виртуальное свойство, вычисленное из границ, позиции(
UIView
' s center), и преобразование.Итак, в основном, как макеты слоев/представлений действительно решаются этими тремя свойствами (и точкой привязки), и ни одно из этих трех свойств не изменит никакого другого свойства, например, изменение преобразования не меняет границ.
есть очень хорошие ответы с подробным объяснением этого поста. Я просто хотел бы сослаться на то, что есть еще одно объяснение с визуальным представлением значения Frame, Bounds, Center, Transform, Bounds Origin в видео WWDC 2011 Понимание Программирования С Использованием UIKit Перевода начиная с @4:22 до 20:10
после прочтения приведенных выше ответов, здесь добавляются мои интерпретации.
предположим, просмотр в интернете,браузер ваш
frame
, который решает, где и как большой, чтобы показать веб-страницы. скроллер браузер-это вашbounds.origin
это решает, какая часть веб-страницы будет показана.bounds.origin
- это трудно понять. Лучший способ узнать-это создать приложение с одним представлением, попытаться изменить эти параметры и посмотреть, как меняются подвиды.- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. UIView *view1 = [[UIView alloc] initWithFrame:CGRectMake(100.0f, 200.0f, 200.0f, 400.0f)]; [view1 setBackgroundColor:[UIColor redColor]]; UIView *view2 = [[UIView alloc] initWithFrame:CGRectInset(view1.bounds, 20.0f, 20.0f)]; [view2 setBackgroundColor:[UIColor yellowColor]]; [view1 addSubview:view2]; [[self view] addSubview:view1]; NSLog(@"Old view1 frame %@, bounds %@, center %@", NSStringFromCGRect(view1.frame), NSStringFromCGRect(view1.bounds), NSStringFromCGPoint(view1.center)); NSLog(@"Old view2 frame %@, bounds %@, center %@", NSStringFromCGRect(view2.frame), NSStringFromCGRect(view2.bounds), NSStringFromCGPoint(view2.center)); // Modify this part. CGRect bounds = view1.bounds; bounds.origin.x += 10.0f; bounds.origin.y += 10.0f; // incase you need width, height //bounds.size.height += 20.0f; //bounds.size.width += 20.0f; view1.bounds = bounds; NSLog(@"New view1 frame %@, bounds %@, center %@", NSStringFromCGRect(view1.frame), NSStringFromCGRect(view1.bounds), NSStringFromCGPoint(view1.center)); NSLog(@"New view2 frame %@, bounds %@, center %@", NSStringFromCGRect(view2.frame), NSStringFromCGRect(view2.bounds), NSStringFromCGPoint(view2.center));