1.布局 Layout
什麼是布局
- 是指在一個視圖中,如何擺放它的子視圖 (設定子視圖的位置和大小)
如何布局?
方法一: 純代碼布局 (古老的方法)
- 理念:當螢幕發生變化時,自動執行一段代碼,在代碼中根據新的螢幕大小重新計算各個視圖的frame,進而達到重新定位的目的
- 特點:功能強大,非常繁瑣
-(void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
//純代碼布局
CGFloat viewWidth = (self.view.bounds.size.width - ) / ;
CGRect frame = self.myView1.frame;
frame.origin.x = ;
frame.origin.y = ;
frame.size.width = viewWidth;
frame.size.height = ;
self.myView1.frame = frame;
frame.origin.x += + viewWidth;
self.myView2.frame = frame;
}
方法二: Auto Resizing 以前的一種自動布局技術
- 理念:根據螢幕的等比變化,同樣等比調整視圖的距離上下左右邊緣的距離,或等比調整視圖的大小
- 特點:簡單易用
- (void)viewDidLoad {
[super viewDidLoad];
UIView *myView = [[UIView alloc]init];
myView.frame = CGRectMake(self.view.frame.size.width - - , , , );
myView.backgroundColor = [UIColor redColor];
//手動設定 AutoResizing 這裡和故事版中點亮紅線的方向是反
myView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleBottomMargin;
[self.view addSubview:myView];
}
方法三:Auto Layout 最新的自動布局方法
- 理念:将視圖所在的位置使用多個限制條件描述出來,當螢幕大小發生變化時,系統會自動根據設定的多個限制,由系統計算出 不違背所有條件的一個合适的frame
- 工作原理
- 通過一系列的“限制constraint”來描述視圖的展示位置
- 什麼是限制?代表一個條,隻需要設定一些限制,則系統會根據這一堆限制,自動計算出符合限制的frame
- 如何建立限制?
- 方式一:用代碼建立
- 方式二:在故事版中可視化配置
- 限制的兩個原則
- 1.描述清楚 (x, y, w, h 全部通過限制描述出來)
- 2.互不沖突
- 使用代碼建立AutoLayout限制
-
如何實作:
step1:建立限制對象 NSLayoutConstraint
step2:将限制對象加入到視圖的父試圖中
-
- 建立一個限制對象
- 方式一 : 萬能公式法
-
view1.attr < relation> view2.attr *multiplier + constant
文字描述:按鍵1距離視圖的左邊為20個點
公式描述:button1.left = self.view.left * 1 + 20
文字描述:按鍵1的寬度是按鍵2寬度的一半
公式描述:button1.width = button2.width * 0.5 + 0
文字描述:按鍵1的右邊和按鍵2的左邊間隔10
公式描述:button1.right = button2.left * 1 + 10
-
- 方式一 : 萬能公式法
- (void)viewDidLoad {
[super viewDidLoad];
UIView *myView1 = [[UIView alloc]init];
myView1.backgroundColor = [UIColor redColor];
UIView *myView2 = [[UIView alloc]init];
myView2.backgroundColor = [UIColor greenColor];
[self.view addSubview:myView1];
[self.view addSubview:myView2];
//關閉系統 Autoresizing
myView1.translatesAutoresizingMaskIntoConstraints = NO;
myView2.translatesAutoresizingMaskIntoConstraints = NO;
/**建立左邊view的限制對象**/
//左邊距離螢幕左邊 20
NSLayoutConstraint *c1 = [NSLayoutConstraint constraintWithItem:myView1 attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier: constant:];
//上邊距離螢幕頂部 20
NSLayoutConstraint *c2 = [NSLayoutConstraint constraintWithItem:myView1 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier: constant:];
//myView1的寬度 等于 myView2的寬度
NSLayoutConstraint *c3 = [NSLayoutConstraint constraintWithItem:myView1 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:myView2 attribute:NSLayoutAttributeWidth multiplier: constant:];
//高度為 40
NSLayoutConstraint *c4 = [NSLayoutConstraint constraintWithItem:myView1 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier: constant:];
//限制對象添加到父試圖上
[self.view addConstraint:c1];
[self.view addConstraint:c2];
[self.view addConstraint:c3];
[self.view addConstraint:c4];
/**myView2 限制**/
//頂部
NSLayoutConstraint *c5 = [NSLayoutConstraint constraintWithItem:myView2 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier: constant:];
//高度
NSLayoutConstraint *c6 = [NSLayoutConstraint constraintWithItem:myView2 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier: constant:];
//右邊
NSLayoutConstraint *c7 = [NSLayoutConstraint constraintWithItem:myView2 attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier: constant:-];
//左邊
NSLayoutConstraint *c8 = [NSLayoutConstraint constraintWithItem:myView2 attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:myView1 attribute:NSLayoutAttributeRight multiplier: constant:];
//限制對象添加到父試圖上
[self.view addConstraint:c5];
[self.view addConstraint:c6];
[self.view addConstraint:c7];
[self.view addConstraint:c8];
}
- 方法二: VFL 法 (Visual Format Language)
- 是什麼?
- 一個字元串,具有一定的格式,不同的格式代表不同的限制,并且,一個字元串往往能一次性表達出多個限制
-
如何寫VFL字元串?
- 文字:button1和button2之間的間距為30
- VFL:[button1]-30-[button]
- 文字:button1的寬度為50
- VFL:[button1(==50)] 或 [button1(50)]
- 文字:button1 距離 左邊20,button2距離右邊20, button1和button2間隔10, button1寬度和button2的寬度相等
- VFL: |-20-[button1(button2)]-10-[button2(button1)]-20-|
- 文字:button1 距離頂部 為20
- VFL: V:|-20-[button1]
- 文字:button1 和 button2 垂直方向間隔10
- VFL: V:[button1]-10-[button2]
-
VFL 特殊符号的含義
| 代表父視圖的邊緣
H:| 代表父試圖的左邊緣
V:| 代表父試圖的上邊緣
[] 代表一個子視圖
() 代表一個寬度或高度的條件
-x- 代表間距是 x
-代表标準間距 8
- 是什麼?
- (void)viewDidLoad {
[super viewDidLoad];
UIView *view1 = [[UIView alloc]init];
view1.backgroundColor = [UIColor redColor];
UIView *view2 = [[UIView alloc]init];
view2.backgroundColor = [UIColor greenColor];
[self.view addSubview:view1];
[self.view addSubview:view2];
//關閉 autoresizing 自動翻譯限制的 功能
view1.translatesAutoresizingMaskIntoConstraints = NO;
view2.translatesAutoresizingMaskIntoConstraints = NO;
//VFL表達式
//1.準備一個 VFL
NSString *hVFL = @"H:|-left-[view1]-space-[view2(view1)]-right-|";
//建立垂直方向限制
NSString *vVFL = @"V:|-top-[view1(40)]";
//建立一個對照表
NSDictionary *metricsDic = @{
@"left":@,
@"right":@,
@"space":@,
@"top":@};
//該宏會建立 一個字典, 該字典的value就是傳入的對象, 該字典會自動使用傳入的對象的名稱 作為key
NSDictionary *dic = NSDictionaryOfVariableBindings(view1,view2);
NSArray<NSLayoutConstraint*> *constraints = [NSLayoutConstraint constraintsWithVisualFormat:hVFL options:NSLayoutFormatAlignAllTop | NSLayoutFormatAlignAllBottom metrics:metricsDic views:dic];
NSArray<NSLayoutConstraint*> *constraints2 = [NSLayoutConstraint constraintsWithVisualFormat:vVFL options:NSLayoutFormatAlignAllTop metrics:metricsDic views:dic];
// NSArray<NSLayoutConstraint*> *constraints = [NSLayoutConstraint constraintsWithVisualFormat:hVFL options:NSLayoutFormatAlignAllTop | NSLayoutFormatAlignAllBottom metrics:nil views:@{@"view1":view1, @"view2":view2}];
// NSArray<NSLayoutConstraint*> *constraints2 = [NSLayoutConstraint constraintsWithVisualFormat:vVFL options:NSLayoutFormatAlignAllTop metrics:nil views:@{@"view1":view1}];
[self.view addConstraints:constraints];
[self.view addConstraints:constraints2];
}