Оскільки питання, яке я задавав, було бачено багато разів, я надам детальну відповідь на нього. Ви можете змінити його, якщо хочете додати більш правильний вміст.
Спочатку резюме на питання: рамка, межі та центр та їхні стосунки.
Кадр Вид frame
( CGRect
) - це положення його прямокутника в системі superview
координат. За замовчуванням він починається вгорі зліва.
Межі Огляд bounds
( CGRect
) виражає прямокутник перегляду у власній системі координат.
Центрcenter
є CGPoint
вираженим в термінах superview
системи «s координат і визначає положення точної центральної точки зору.
Узяті з позиції UIView + , це відносини (вони не працюють у коді, оскільки вони є неформальними рівняннями) серед попередніх властивостей:
ПРИМІТКА. Ці відносини не застосовуються при повороті поглядів. Для отримання додаткової інформації я запропоную вам поглянути на наступне зображення, зроблене з кухонного ящика на базі курсу 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
«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, це призведе до того, що субпрезентація буде відсічена до меж приймача. Якщо встановлено НІ, підзагляди, рамки яких виходять за межі видимих меж приймача, не відсікаються. Значення за замовчуванням - НІ.
Іншими словами, якщо перегляд frame
є, (0, 0, 100, 100)
а його підвід - (90, 90, 30, 30)
це лише ви, ви побачите лише частину цього перегляду. Останній не перевищує межі батьківського подання.
masksToBounds
еквівалентно clipsToBounds
. Замість а UIView
, ця властивість застосовується до а CALayer
. Під капотом clipsToBounds
дзвонить masksToBounds
. Для подальших посилань дивіться, як співвідношення кліпів UIViewToBounds та масок CALayerToBounds? .