天天看點

OC-Layout自動布局-AutoResizing&AutoLayout&1.布局 Layout

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];




}