Тъй като въпросът, който зададох, е виждан много пъти, ще дам подробен отговор на него. Чувствайте се свободни да го промените, ако искате да добавите по-правилно съдържание.
Първо обобщение на въпроса: рамка, граници и център и техните взаимоотношения.
Рамка frame
(CGRect
) на изглед е позицията на неговия правоъгълник в координатната система на superview
. По подразбиране започва горе вляво.
Граници bounds
(CGRect
) на изглед изразява правоъгълник на изглед в неговата собствена координатна система.
Център center
е CGPoint
, изразено чрез координатната система на superview
и определя позицията на точната централна точка на изгледа.
Взети от UIView + позиция това са връзките (те не t работят в код, тъй като те са неофициални уравнения) сред предишните свойства:
ЗАБЕЛЕЖКА: Тези връзки не се прилагат, ако изгледите са завъртани. За допълнителна информация ще ви предложа да разгледате следното изображение, взето от The Kitchen Drawer< /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 doc)
Задаването на тази стойност на 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