zoukankan      html  css  js  c++  java
  • iOS开发之Autolayout

    1、概述

    在以前的iOS程序中,是如何设置布局UI界面的?

    (1)经常编写大量的坐标计算代码

    (2)为了保证在3.5 inch和4.0 inch屏幕上都能有完美的UI界面效果,有时还需要分别为2种屏幕编写不同的坐标计算代码(即传说中的“屏幕适配”)

    什么是Autolayout

    (1)Autolayout是一种“自动布局”技术,专门用来布局UI界面的

    (2)Autolayout自iOS 6开始引入,由于Xcode 4的不给力,当时并没有得到很大推广

    (3)自iOS 7(Xcode 5)开始,Autolayout的开发效率得到很大的提升

    (4)苹果官方也推荐开发者尽量使用Autolayout来布局UI界面

    (5)Autolayout能很轻松地解决屏幕适配的问题

    Autoresizing

    (1)在Autolayout之前,有Autoresizing可以作屏幕适配,但局限性较大,有些任务根本无法完成

    (2)相比之下,Autolayout的功能比Autoresizing强大很多

    Autolayout2个核心概念:

    (1)参照

    (2)约束

    2Autolayout的警告和错误

    警告:

    控件的frame不匹配所添加的约束, 比如:

    约束控件的宽度为100, 而控件现在的宽度是110

    错误:

    缺乏必要的约束, 比如:

    只约束了宽度和高度, 没有约束具体的位置

    两个约束冲突, 比如:

    1个约束控件的宽度为100, 1个约束控件的宽度为110

    3、代码实现Autolayout

    代码实现Autolayout的步骤:

    第一步:利用NSLayoutConstraint类创建具体的约束对象

    第二步:添加约束对象到相应的view上

    - (void)addConstraint:(NSLayoutConstraint *)constraint;

    - (void)addConstraints:(NSArray *)constraints;

    代码实现Autolayout的注意点:

    (1)要先禁止autoresizing功能,设置view的下面属性为NO

    view.translatesAutoresizingMaskIntoConstraints = NO;

    (2)添加约束之前,一定要保证相关控件都已经在各自的父控件上

    (3)不用再给view设置frame

    4NSLayoutConstraint

    一个NSLayoutConstraint对象就代表一个约束。

    创建约束对象的常用方法:

    +(id)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;

    view1 :要约束的控件

    attr1 :约束的类型(做怎样的约束)

    relation :与参照控件之间的关系

    view2 :参照的控件

    attr2 :约束的类型(做怎样的约束)

    multiplier :乘数

    c :常量

    自动布局有个核心公式:

    obj1.property1 =(obj2.property2 * multiplier)+ constant value

    例如:实现下面效果:

    - (void)viewDidLoad

    {

        [super viewDidLoad];

       

        // 1.添加控件

        UIView *blueView = [[UIView alloc] init];

        blueView.backgroundColor = [UIColor blueColor];

        blueView.translatesAutoresizingMaskIntoConstraints = NO;

        [self.view addSubview:blueView];

       

        UIView *redView = [[UIView alloc] init];

        redView.backgroundColor = [UIColor redColor];

        redView.translatesAutoresizingMaskIntoConstraints = NO;

        [self.view addSubview:redView];

       

        // 2.约束蓝色

        // 2.1.高度

    NSLayoutConstraint *blueHeight =

    [NSLayoutConstraint constraintWithItem:blueView attribute:

    NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:

    nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0

    constant:40];

        [blueView addConstraint:blueHeight];

        // 2.2.左边间距

        CGFloat margin = 20;

    NSLayoutConstraint *blueLeft =

    [NSLayoutConstraint constraintWithItem:blueView attribute:

    NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:

    self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:

    margin];

        [self.view addConstraint:blueLeft];

        // 2.3.顶部间距

    NSLayoutConstraint *blueTop =

    [NSLayoutConstraint constraintWithItem:blueView attribute:

    NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:

    self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:

    margin];

        [self.view addConstraint:blueTop];

        // 2.4.右边间距

    NSLayoutConstraint *blueRight =

     [NSLayoutConstraint constraintWithItem:blueView attribute:

    NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:

    self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant:

    -margin];

        [self.view addConstraint:blueRight];

       

        // 3.约束红色

        // 3.1.让红色右边 == 蓝色右边

    NSLayoutConstraint *redRight =

    [NSLayoutConstraint constraintWithItem:redView attribute:

    NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:

    blueView attribute:NSLayoutAttributeRight multiplier:1.0

    constant:0.0];

        [self.view addConstraint:redRight];

        // 3.2.让红色高度 == 蓝色高度

    NSLayoutConstraint *redHeight =

    [NSLayoutConstraint constraintWithItem:redView attribute:

    NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:

    blueView attribute:NSLayoutAttributeHeight multiplier:1.0 constant:

    0.0];

        [self.view addConstraint:redHeight];

       

        // 3.3.让红色顶部 == 蓝色底部 + 间距

    NSLayoutConstraint *redTop =

    [NSLayoutConstraint constraintWithItem:redView attribute:

    NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:

    blueView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:

    margin];

        [self.view addConstraint:redTop];

       

        // 3.4.让红色宽度 == 蓝色宽度 * 0.5

    NSLayoutConstraint *redWidth =

    [NSLayoutConstraint constraintWithItem:redView attribute:

    NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:

    blueView attribute:NSLayoutAttributeWidth multiplier:0.5 constant:

    0.0];

        [self.view addConstraint:redWidth];

    }

    5、添加约束的规则

    在创建约束之后,需要将其添加到作用的view上。

    在添加时要注意目标view需要遵循以下规则:

    (1)对于两个同层级view之间的约束关系,添加到它们的父view上

    (2)对于两个不同层级view之间的约束关系,添加到他们最近的共同父view上

    (3)对于有层次关系的两个view之间的约束关系,添加到层次较高的父view上

    6VFL语言

    什么是VFL语言?

    VFL全称是Visual Format Language,翻译过来是“可视化格式语言”,是苹果公司为了简化Autolayout的编码而推出的抽象语言。

    7VFL示例

    H:[cancelButton(72)]-12-[acceptButton(50)]

    canelButton宽72,acceptButton宽50,它们之间间距12

    H:[wideView(>=60@700)]

    wideView宽度大于等于60point,该约束条件优先级为700(优先级最大值为1000,优先级越高的约束越先被满足)

    V:[redBox]-[yellowBox(==redBox)]

    竖直方向上,先有一个redBox,其下方紧接一个高度等于redBox高度的yellowBox

    H:|-10-[Find]-[FindNext]-[FindField(>=20)]-|

    水平方向上,Find距离父view左边缘默认间隔宽度,之后是FindNext距离Find间隔默认宽度;再之后是宽度不小于20的FindField,它和FindNext以及父view右边缘的间距都是默认宽度。(竖线“|” 表示superview的边缘)

    8VFL的使用

    使用VFL来创建约束数组:

    + (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views;

    format :VFL语句

    opts :约束类型

    metrics :VFL语句中用到的具体数值

    views :VFL语句中用到的控件

    创建一个字典(内部包含VFL语句中用到的控件)的快捷宏定义:

    NSDictionaryOfVariableBindings(...)

    例如:

    NSDictionary *views =

    NSDictionaryOfVariableBindings(blueView, redView);

    NSArray *conts2 =

    [NSLayoutConstraint constraintsWithVisualFormat:

    @"V:[blueView(==blueHeight)]-margin-|" options:0 metrics:

    @{@"blueHeight" : @40, @"margin" : @20} views:views];

    示例代码:

    - (void)viewDidLoad

    {

        [super viewDidLoad];

       

        // 1.添加控件

        UIView *blueView = [[UIView alloc] init];

        blueView.backgroundColor = [UIColor blueColor];

        blueView.translatesAutoresizingMaskIntoConstraints = NO;

        [self.view addSubview:blueView];

       

        UIView *redView = [[UIView alloc] init];

        redView.backgroundColor = [UIColor redColor];

        redView.translatesAutoresizingMaskIntoConstraints = NO;

        [self.view addSubview:redView];

       

        // 2.VFL生成约束

    NSArray *conts =

     [NSLayoutConstraint constraintsWithVisualFormat:

    @"H:|-20-[blueView]-20-|" options:0 metrics:nil views:

    @{@"blueView" : blueView}];

        [self.view addConstraints:conts];

       

    NSArray *conts2 =

     [NSLayoutConstraint constraintsWithVisualFormat:

    @"V:|-20-[blueView(40)]-20-[redView(==blueView)]" options:NSLayoutFormatAlignAllRight metrics:nil views:@{@"blueView" : blueView, @"redView" : redView}];

        [self.view addConstraints:conts2];

       

    NSLayoutConstraint *redWidth =

     [NSLayoutConstraint constraintWithItem:redView attribute:

    NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:

    blueView attribute:NSLayoutAttributeWidth multiplier:0.5 constant:

    0.0];

        [self.view addConstraint:redWidth];

    }}

    运行效果图:

    9有了AutolayoutUILabel

    在没有Autolayout之前,UILabel的文字内容总是居中显示,导致顶部和底部会有一大片空缺区域:

    有Autolayout之后,UILabel的bounds默认会自动包住所有的文字内容,顶部和底部不再会有空缺区域:

    10基于Autolayout的动画

    在修改了约束之后,只要执行下面代码,就能做动画效果:

    [UIView animateWithDuration:1.0 animations:^{

        [添加了约束的view layoutIfNeeded];

    }];

    例如:

    self.leftMargin.constant = 100;

    self.width.constant = 200;

    [UIView animateWithDuration:2.0 animations:^{

         //父控件和redView都添加了约束

         [self.view layoutIfNeeded];

         [self.redView layoutIfNeeded];

    }];

  • 相关阅读:
    LeetCode Power of Three
    LeetCode Nim Game
    LeetCode,ugly number
    LeetCode Binary Tree Paths
    LeetCode Word Pattern
    LeetCode Bulls and Cows
    LeeCode Odd Even Linked List
    LeetCode twoSum
    549. Binary Tree Longest Consecutive Sequence II
    113. Path Sum II
  • 原文地址:https://www.cnblogs.com/lifengfneg/p/4774077.html
Copyright © 2011-2022 走看看