Рамка 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вид. Например, если вы изменитеboundssizeна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));кроме того, если вы измените
boundsoriginизменитьoriginего внутренней системы координат. По умолчаниюoriginна(0.0, 0.0)(верхний левый угол). Например, если вы изменитеoriginнаview1вы можете увидеть (прокомментируйте предыдущий код, если хотите), что теперь верхний левый угол дляview2умиляетview1один. Мотивация довольно проста. Ты говоришьview1что его верхний левый угол теперь находится в положении(20.0, 20.0)но с тех порview2' sframeoriginначинается с(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));








