前言

    NS_CLASS_AVAILABLE_IOS(6_0) @interface NSLayoutConstraint : NSObject@available(iOS 6.0, *)    public class NSLayoutConstraint : NSObject
  • 1)Autolayout

    • 在 Autolayout 之前,有 Autoresizing 可以作屏幕适配,但局限性较大,有些任务根本无法完成(只能解决子控件跟父控件的相对关系问题,不能解决兄弟控件的相对关系问题)。相比之下,Autolayout 的功能比 Autoresizing 强大很多。

    • Auto Layout 是苹果在 iOS 6 (Xcode 4) 中新引入的布局方式,旨在解决 3.5 寸和 4 寸屏幕的适配问题,由于 Xcode 4 的不给力,当时并没有得到很大推广,自 iOS 7(Xcode 5)开始,Auto Layout 的开发效率得到很大的提升。屏幕适配工作在 iPhone 6 及 plus 发布以后变得更加重要,苹果官方也推荐开发者尽量使用 Autolayout 来布局 UI 界面,Autolayout 能很轻松地解决屏幕适配的问题。

    • Autolayout 的 2 个核心概念:
      • 参照
      • 约束
  • 2)约束

    • Auto Layout 的本质是依靠某几项约束条件来达到对某一个元素的定位。我们可以在某个地方只使用一个约束,以达到一个小目的,例如防止内容遮盖、防止边界溢出等。但实践证明,如果把页面上每一个元素的位置都用 Auto Layout 进行 “严格约束” 的话,那么 Auto Layout 可以帮我们省去非常多的计算 frame 的代码。

    • “严格约束” 是什么?简单来说,严格约束就是对某一个元素的绝对定位,让它在任一屏幕尺寸下都有着唯一的位置。这里的绝对定位不是定死的位置,而是对一个元素完善的约束条件。我们要在一个直角坐标系里描述一个矩形。那么只需要指定这个矩形的位置和大小。那么只要给出上图中的四个值即可:到左边界的距离,到上边界的距离,宽度,高度。这四个约束是最简单的情况。在对一个元素进行严格约束时,请直接在脑中构建这个元素,并且加上几条约束条件,如果他无法缩放和动弹,那么严格约束就是成功的!必须牢记,使用 Auto Layout 时最重要的是:对页面上每一个元素都进行严格约束,不严格的约束是万恶之源。

    • 约束主要分为以下几种:
      • 相对于父 view 的约束。如:距离上边距 10,左边距 10。
      • 相对于前一个元素的约束。如:距离上一个元素 20,距离左边的元素 5 等。
      • 对齐类约束。如:跟父 view 左对齐,跟上一个元素居中对齐等。
      • 相等约束。如:跟父 view 等宽。
    • 约束特点:
      • Constraint 可以跨层级

        • 层级中不能有⾃己实现 layoutsubViews 的 View;
        • 不能连接有可变边界的 View,如 ScrollView。
      • Constraint 不会替换前一个。

      • 控件知道⾃己内容⼤⼩。

    • 约束添加的规则:

      • 在创建约束之后,需要将其添加到作用的 view 上,在添加时要注意目标 view 需要遵循以下规则:

        • 相对于父视图的约束,添加到父视图上;
        • 相对于另一个控件的约束,添加到其共有的父视图上;
        • 跨层级的约束,添加到其最上层的父视图上;
        • 自身的宽高等约束,添加到自身视图上。

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

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

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

1、SB/Xib 中 AutoLayout 的设置

  • AutoLayout 使用流程:

    • 启动 AutoLayout 功能。

      • 勾选 Use Auto Layout(默认是开启的)。

    • 摆好控件位置。
    • 添加约束。
    • 给动态的 View 添加 placeholder。
      • 自定义的 View 若要实现 AutoLayout,需要在 Show the Size Inspector 选项卡中设置 Intrinsic Size 为 Placeholder,并实现下面方法。

            - (CGSize)intrinsicContentSize NS_AVAILABLE_IOS(6_0);
    • 更新 constraints 和 frame。
    • 解决有问题的约束。

1.1 添加对齐约束

  • 添加对齐约束

    Leading Edges 左边缘对齐
    Trailing Edges 右边缘对齐
    Top Edges 上边缘对齐
    Bottom Edges 下边缘对齐
    Horizontal Centers 水平中心对齐
    Vertical Centers 垂直中心对齐
    Baselines 文本底标线对齐,大多数控件中等同于 Bottom Edges
    Horizontal Center in Container 在父控件中水平居中
    Vertical Center in Container 在父控件中垂直居中
    Update Frames 根据约束条件更新 Frame

    None 不更新
    Items of New Constraints 新添加约束的元素
    All Frames in Container 容器内的所有 Frame

1.2 添加相对约束

  • 添加相邻、自身、相等约束

    Spacing to nearest neighbor 与相邻的控件间的距离
    Constrain to margins 边缘约束(用于防边缘触摸,选中自动缩进 20)
    Width 控件的宽度
    Height 控件的高度
    Equal Widths 相等的宽度
    Equal Heights 相等的高度
    Aspect Ratio 相等的长宽比
    Align 对齐方式
    Update Frames 根据约束条件更新 Frame

    Use Standard Value 使用标准值
    Use Current Canvas Value 使用当前值
    View 视图控件
    Top Layout Guide 状态栏下边缘处

    Use Standard Value 使用标准值
    Use Current Canvas Value 使用当前值
    Buttom Layout Guide 屏幕下边缘处
    View 视图控件

1.3 处理约束

  • 更新、添加、清除约束

    Selected Views 选中的控件
    -- Update Frames 更新 Frame
    -- Update Constraints 更新约束
    -- Add Missing Constraints 添加缺失的约束
    -- Reset to Suggested Constraints 添加建议的(自动)约束
    -- Clear Constraints 清除约束
    All Views in View Controller 所有控件
    -- Update Frames 更新 Frame
    -- Update Constraints 更新约束
    -- Add Missing Constraints 添加缺失的约束
    -- Reset to Suggested Constraints 添加建议的(自动)约束
    -- Clear Constraints 清除约束

1.4 修改约束

  • 更改添加的约束

  • 方式 1:

    • 选中添加的约束

    • 修改约束的设置

      First Item 第一个控件的约束值,要设置的控件
      Relation 第一个控件与第二个控件约束值之间的关系
      -- Second Item 第二个控件的约束值,参照的控件
      -- Constraint 约束值增加量
      -- Priority 约束优先级
      -- Multiplier 约束值放大倍数
      -- Placeholder
      ---- Remove at build time 编译时移除该约束
      -- Installed 添加该约束

      Leading Margin 左边距
      Center X Within Margins 父控件水平中心
      Trailing Margin 右边距
      Relative to margin 相对于边缘
      respect language direction 遵循本地语言方向
      Reverse First And Second Item 调换 First 和 Second 两个控件的设置位置

      Less Than or Equal 小于等于
      Equal 等于
      Greater Than or Equal 大于等于

      Required(1000) 默认优先级(高优先级)
      High(750) 中优先级
      Low(250) 低优先级

      Reverse Multiplier 反转倍数(即 0.5 变为 2,4:3 变为 3:4)
      Convert to Decimal 转换为十进制
      Presets 预设值(也可以不使用预设值,自己设置需要的倍数,如 0.5)
      -- 1 1 倍
      -- 4:3 4:3 倍
      -- 16:9 16:9 倍
  • 方式 2:

    • 选中设置约束的控件

    • 修改约束的设置

1.5 约束设置警告和错误

  • 警告:

    • 控件的 frame 不匹配所添加的约束。比如约束控件的宽度为 100, 而控件现在的宽度是 110。
  • 错误:

    • 缺乏必要的约束。比如只约束了宽度和高度, 没有约束具体的位置。
    • 两个约束冲突。比如 1 个约束控件的宽度为 100, 1 个约束控件的宽度为 110。

1.6 约束值设置代码

  • Objective-C

        // 将约束关联到代码中@property (weak, nonatomic) IBOutlet NSLayoutConstraint *redViewWidthConstraint;// 获取约束的值/*获取到的 constant 值为 CGFloat 型数值*/CGFloat widthConstant = self.redViewWidthConstraint.constant;// 设置约束的值/*直接给 constant 赋 CGFloat 型数值*/self.redViewWidthConstraint.constant = 50.0;
  • Swift

        // 将约束关联到代码中@IBOutlet weak var redViewWidthConstraint: NSLayoutConstraint!// 获取约束的值/*获取到的 constant 值为 CGFloat 型数值*/let widthConstant = self.redViewWidthConstraint.constant// 设置约束的值/*直接给 constant 赋 CGFloat 型数值*/self.redViewWidthConstraint.constant = 50.0

1.7 Size Classes 设置

  • 适配不同类型的屏幕

    • 在同一个文件中设置不同类型的屏幕尺寸适配。
    • 选择不同尺寸的宽度和高度的组合,可以设置在不同类型屏幕上加载不同的控件或约束。

    • 启动 Size Classes 功能。
      • 勾选 Use Size Classes(默认是开启的)。

2、纯代码中 AutoLayout 的设置

  • 代码实现 Autolayout 的步骤:

    • 利用 NSLayoutConstraint 类创建具体的约束对象。
    • 添加约束对象到相应的 view 上。
  • 代码实现 Autolayout 的注意点:
    • 要先禁止 autoresizing 功能,设置要添加约束的控件的下面属性为 NO。

          redView.translatesAutoresizingMaskIntoConstraints = NO;
    • 添加约束之前,一定要保证相关控件都已经在各自的父控件上。

          [self.view addSubview:redView];
    • 不用再给 view 设置 frame。

    • 如果是 View Controller,则 AutoLayout 适配写在下面方法中。

          - (void)updateViewConstraints NS_AVAILABLE_IOS(6_0);
    • 如果是 View,则 AutoLayout 适配写在下面方法中。

          - (void)updateConstraints NS_AVAILABLE_IOS(6_0);
  • VFL 语言:

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

    • VFL 语言格式

    • VFL 语言示例

          // canelButton 宽 72,acceptButton 宽 50,它们之间间距 12。H:[cancelButton(72)]-12-[acceptButton(50)]// wideView 宽度大于等于 60point,该约束条件优先级为 700(优先级最大值为 1000,优先级越高的约束越先被满足)。H:[wideView(>=60@700)]// 竖直方向上,先有一个 redBox,其下方紧接一个高度等于 redBox 高度的 yellowBox。V:[redBox][yellowBox(==redBox)]// 水平方向上,Find 距离父 view 左边缘默认间隔宽度,之后是 FindNext 距离 Find 间隔默认宽度;// 再之后是宽度不小于 20 的 FindField,它和 FindNext 以及父 view 右边缘的间距都是默认宽度。// 竖线 “|” 表示 superview 的边缘。H:|-10-[Find]-[FindNext]-[FindField(>=20)]-|

2.1 约束设置方法

  • Objective-C

        // 获取当前 view 中所有的约束- (NSArray *)constraints  NS_AVAILABLE_IOS(6_0);// 将指定的约束添加到页面,相对于另一个视图的约束必须添加到其父视图上- (void)addConstraint:(NSLayoutConstraint *)constraint     NS_AVAILABLE_IOS(6_0);- (void)addConstraints:(NSArray *)constraints              NS_AVAILABLE_IOS(6_0);// 将指定的约束从页面中移除- (void)removeConstraint:(NSLayoutConstraint *)constraint  NS_AVAILABLE_IOS(6_0);- (void)removeConstraints:(NSArray *)constraints           NS_AVAILABLE_IOS(6_0);// 激活或者停用指定约束@property (getter=isActive) BOOL active                    NS_AVAILABLE(10_10, 8_0);// 激活指定约束+ (void)activateConstraints:(NSArray *)constraints     NS_AVAILABLE(10_10, 8_0);// 停用指定约束+ (void)deactivateConstraints:(NSArray *)constraints   NS_AVAILABLE(10_10, 8_0);
    
        // 获取现有约束NSArray *constraints = [self.view constraints];// 添加约束[self.view addConstraint:constraintX];[self.view addConstraint:constraintY];[redView addConstraint:constraintW];[redView addConstraint:constraintH];[self.view addConstraints:@[constraintX, constraintY, constraintW, constraintH]];// 激活指定约束constraintX.active = YES;constraintY.active = YES;constraintW.active = YES;constraintH.active = YES;[NSLayoutConstraint activateConstraints:@[constraintX, constraintY, constraintW, constraintH]];// 删除约束[self.view removeConstraint:constraintX];[self.view removeConstraint:constraintY];[self.view removeConstraints:@[constraintX, constraintY]];// 停用指定约束constraintX.active = NO;constraintY.active = NO;[NSLayoutConstraint deactivateConstraints:@[constraintX, constraintY]];
  • Swift

        // 获取当前 view 中所有的约束public var constraints: [NSLayoutConstraint] { get }   @available(iOS 6.0, *)// 将指定的约束添加到页面,相对于另一个视图的约束必须添加到其父视图上public func addConstraint(constraint: NSLayoutConstraint)       @available(iOS 6.0, *)public func addConstraints(constraints: [NSLayoutConstraint])   @available(iOS 6.0, *)// 将指定的约束从页面中移除public func removeConstraint(constraint: NSLayoutConstraint)       @available(iOS 6.0, *)public func removeConstraints(constraints: [NSLayoutConstraint])   @available(iOS 6.0, *)// 激活或者停用指定约束public var active: Bool    @available(iOS 8.0, *)// 激活指定约束public class func activateConstraints(constraints: [NSLayoutConstraint])    @available(iOS 8.0, *)// 停用指定约束public class func deactivateConstraints(constraints: [NSLayoutConstraint])  @available(iOS 8.0, *)
    
        // 获取现有约束let constraints = self.view.constraints()// 添加约束self.view.addConstraint(constraintX)self.view.addConstraint(constraintY)redView.addConstraint(constraintW)redView.addConstraint(constraintH)self.view.addConstraints([constraintX, constraintY, constraintW, constraintH])// 激活指定约束constraintX.active = trueconstraintY.active = trueconstraintW.active = trueconstraintH.active = trueNSLayoutConstraint.activateConstraints([constraintX, constraintY, constraintW, constraintH])// 删除约束self.view.removeConstraint(constraintX)self.view.removeConstraint(constraintY)self.view.removeConstraints([constraintX, constraintY])// 停用指定约束constraintX.active = falseconstraintY.active = falseNSLayoutConstraint.deactivateConstraints([constraintX, constraintY])

2.2 关闭 Autoresizing

  • Objective-C

        // 纯代码添加约束必须先关闭 Autoresizing/*不要将 AutoresizingMask 转为 Autolayout 的约束每个添加约束的控件都需要设置*/redView.translatesAutoresizingMaskIntoConstraints = NO;
  • Swift

        // 纯代码添加约束必须先关闭 Autoresizing/*不要将 AutoresizingMask 转为 Autolayout 的约束每个添加约束的控件都需要设置*/redView.translatesAutoresizingMaskIntoConstraints = false

2.3 常规语句方式添加约束

  • Objective-C

        + (instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(nullable id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;参数说明:第一个参数 view1: 要约束的控件;第二个参数 attr1: 约束的类型(做怎样的约束);第三个参数 relation: 与参照控件之间的关系;第四个参数 view2: 参照的控件;第五个参数 attr2: 约束的类型(做怎样的约束);第六个参数 multiplier: 乘数,控件 1 的指定属性是参照控件 2 指定属性的多少倍;第七个参数 c: 常量,控件 1 的指定属性需要加的浮点数。根据参数的讲解,得出计算公式如下:view1.attr1 [= , >= , <=] view2.attr2 * multiplier + c;参数详解:1、NSLayoutAttributeNSLayoutAttributeLeft = 1,             左边缘,CGRectGetMinX(view.frame)NSLayoutAttributeRight,                右边缘,CGRectGetMaxX(view.frame)NSLayoutAttributeTop,                  上边缘,CGRectGetMinY(view.frame)NSLayoutAttributeBottom,               下边缘,CGRectGetMinY(view.frame)NSLayoutAttributeLeading,              前边缘,在习惯由左向右看的地区相当于 Left,在习惯从右至左看的地区相当于 RightNSLayoutAttributeTrailing,             后边缘,在习惯由左向右看的地区相当于 Right,在习惯从右至左看的地区相当于 LeftNSLayoutAttributeWidth,                宽度,CGRectGetWidth(view.frame)NSLayoutAttributeHeight,               高度,CGRectGetHeight(view.frame)NSLayoutAttributeCenterX,              水平中心,view.center.xNSLayoutAttributeCenterY,              垂直中心,view.center.yNSLayoutAttributeBaseline,             文本底标线NSLayoutAttributeLastBaseline = NSLayoutAttributeBaseline, 文本底标线NSLayoutAttributeFirstBaseline         文本上标线,NS_ENUM_AVAILABLE_IOS(8_0)NSLayoutAttributeLeftMargin            左边缘,NS_ENUM_AVAILABLE_IOS(8_0)NSLayoutAttributeRightMargin           右边缘,NS_ENUM_AVAILABLE_IOS(8_0)NSLayoutAttributeTopMargin             上边缘,NS_ENUM_AVAILABLE_IOS(8_0)NSLayoutAttributeBottomMargin          下边缘,NS_ENUM_AVAILABLE_IOS(8_0)NSLayoutAttributeLeadingMargin         前边缘,NS_ENUM_AVAILABLE_IOS(8_0)NSLayoutAttributeTrailingMargin        后边缘,NS_ENUM_AVAILABLE_IOS(8_0)NSLayoutAttributeCenterXWithinMargins  宽度,NS_ENUM_AVAILABLE_IOS(8_0)NSLayoutAttributeCenterYWithinMargins  高度,NS_ENUM_AVAILABLE_IOS(8_0)NSLayoutAttributeNotAnAttribute = 0  清除所有约束2、NSLayoutRelationNSLayoutRelationLessThanOrEqual = -1,     小于等于NSLayoutRelationEqual = 0,                等于NSLayoutRelationGreaterThanOrEqual = 1,   大于等于
        // 创建约束// redView 的左边缘与 greenView 的左边缘对齐NSLayoutConstraint *constraintX = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:greenView attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0];// redView 的上边缘等于 greenView 的上边缘加 100NSLayoutConstraint *constraintY = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:greenView attribute:NSLayoutAttributeTop multiplier:1.0 constant:100];// redView 的宽度等于 100NSLayoutConstraint *constraintW = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nilattribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:100];// redView 的高度等于 50NSLayoutConstraint *constraintH = [NSLayoutConstraint constraintWithItem:redView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nilattribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:50];// 将约束添加到视图上/*相对于另一个视图的约束必须添加到其父视图上*/[self.view addConstraint:constraintX];[self.view addConstraint:constraintY];[redView addConstraint:constraintW];[redView addConstraint:constraintH];
  • Swift

        public convenience init(item view1: AnyObject, attribute attr1: NSLayoutAttribute, relatedBy relation: NSLayoutRelation, toItem view2: AnyObject?, attribute attr2: NSLayoutAttribute, multiplier: CGFloat, constant c: CGFloat)参数说明:第一个参数 view1: 要设置的视图;第二个参数 attr1: view1 要设置的属性;第三个参数 relation: 视图 view1 和 view2 的指定属性之间的关系;第四个参数 view2: 参照的视图;第五个参数 attr2: 参照视图 view2 的属性;第六个参数 multiplier: 视图 view1 的指定属性是参照视图 view2 指定属性的多少倍;第七个参数 c: 视图 view1 的指定属性需要加的浮点数。根据参数的讲解,得出计算公式如下:view1.attr1 [= , >= , <=] view2.attr2 * multiplier + c;参数详解:1、NSLayoutAttributecase Left                   左边缘,CGRectGetMinX(view.frame)case Right                  右边缘,CGRectGetMaxX(view.frame)case Top                    上边缘,CGRectGetMinY(view.frame)case Bottom                 下边缘,CGRectGetMinY(view.frame)case Leading                前边缘,在习惯由左向右看的地区相当于 Left,在习惯从右至左看的地区相当于 Rightcase Trailing               后边缘,在习惯由左向右看的地区相当于 Right,在习惯从右至左看的地区相当于 Leftcase Width                  宽度,CGRectGetWidth(view.frame)case Height                 高度,CGRectGetHeight(view.frame)case CenterX                水平中心,view.center.xcase CenterY                垂直中心,view.center.ycase Baseline               文本底标线case FirstBaseline          文本上标线,@availability(iOS, introduced=8.0)case LeftMargin             左边缘,@availability(iOS, introduced=8.0)case RightMargin            右边缘,@availability(iOS, introduced=8.0)case TopMargin              上边缘,@availability(iOS, introduced=8.0)case BottomMargin           下边缘,@availability(iOS, introduced=8.0)case LeadingMargin          前边缘,@availability(iOS, introduced=8.0)case TrailingMargin         后边缘,@availability(iOS, introduced=8.0)case CenterXWithinMargins   宽度,@availability(iOS, introduced=8.0)case CenterYWithinMargins   高度,@availability(iOS, introduced=8.0)case NotAnAttribute         清除所有约束2、NSLayoutRelationcase LessThanOrEqual       小于等于case Equal                 等于case GreaterThanOrEqual    大于等于
        // 创建约束// redView 的左边缘与 greenView 的左边缘对齐let constraintX = NSLayoutConstraint(item: redView, attribute: .Left, relatedBy: .Equal, toItem: greenView, attribute: .Left, multiplier: 1.0,constant: 0)// redView 的上边缘等于 greenView 的上边缘加 100let constraintY = NSLayoutConstraint(item: redView, attribute: .Top, relatedBy: .Equal, toItem: greenView, attribute: .Top, multiplier: 1.0, constant: 100)// redView 的宽度等于 100let constraintW = NSLayoutConstraint(item: redView, attribute: .Width, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0,constant: 100)// redView 的高度等于 50let constraintH = NSLayoutConstraint(item: redView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0,constant: 50)// 将约束添加到视图上/*相对于另一个视图的约束必须添加到其父视图上*/self.view.addConstraint(constraintX)self.view.addConstraint(constraintY)redView.addConstraint(constraintW)redView.addConstraint(constraintH)

2.4 VFL 语句方式添加约束

  • Objective-C

        // 使用 VFL 来创建约束数组+ (NSArray<__kindof NSLayoutConstraint *> *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(nullable NSDictionary<NSString *,id> *)metrics views:(NSDictionary<NSString *, id> *)views;参数:format  :VFL 语句opts    :约束类型metrics :约束值views   :需要设置约束的控件NSLayoutFormatOptions  约束类型:NSLayoutFormatAlignAllLeft     = (1 << NSLayoutAttributeLeft),         左边缘对齐NSLayoutFormatAlignAllRight    = (1 << NSLayoutAttributeRight),        右边缘对齐NSLayoutFormatAlignAllTop      = (1 << NSLayoutAttributeTop),          上边缘对齐NSLayoutFormatAlignAllBottom   = (1 << NSLayoutAttributeBottom),       下边缘对齐NSLayoutFormatAlignAllLeading  = (1 << NSLayoutAttributeLeading),      前边缘对齐NSLayoutFormatAlignAllTrailing = (1 << NSLayoutAttributeTrailing),     后边缘对齐NSLayoutFormatAlignAllCenterX  = (1 << NSLayoutAttributeCenterX),      水平中心对齐NSLayoutFormatAlignAllCenterY  = (1 << NSLayoutAttributeCenterY),      垂直中心对齐NSLayoutFormatAlignAllBaseline = (1 << NSLayoutAttributeBaseline),     文本底标线对齐NSLayoutFormatAlignAllLastBaseline = NSLayoutFormatAlignAllBaseline,   文本底标线对齐NSLayoutFormatAlignAllFirstBaseline NS_ENUM_AVAILABLE_IOS(8_0) = (1 << NSLayoutAttributeFirstBaseline),文本上标线对齐NSLayoutFormatAlignmentMask = 0xFFFF,                                  无对齐/* choose only one of these three*/NSLayoutFormatDirectionLeadingToTrailing = 0 << 16, // default         由前到后方向,默认NSLayoutFormatDirectionLeftToRight = 1 << 16,                          由左到右方向NSLayoutFormatDirectionRightToLeft = 2 << 16,                          由右到左方向NSLayoutFormatDirectionMask = 0x3 << 16,                               无方向// 使用下面的宏来自动生成 views 和 metrics 参数NSDictionaryOfVariableBindings(...)NSDictionaryOfVariableBindings(redView); 等价于 @{@"redView": redView};
        // 约束值NSNumber *margin = @50;NSNumber *width = @100;NSNumber *height = @50;// 创建水平方向约束/*redView 的宽度为 100kNilOptions = 0,相当于 NSLayoutFormatAlignmentMask*/NSDictionary *viewsH = NSDictionaryOfVariableBindings(redView);NSDictionary *metricsH = NSDictionaryOfVariableBindings(width);NSString *vflH = @"H:[redView(width)]";NSArray *constraintH = [NSLayoutConstraint constraintsWithVisualFormat:vflHoptions:kNilOptionsmetrics:metricsHviews:viewsH];// 创建垂直方向约束/*redView 的上边缘等于 greenView 的上边缘加 100(greenView 的高度为 50)redView 与 greenView 的左边缘对齐redView 的高度等于 50*/NSDictionary *viewsV = NSDictionaryOfVariableBindings(redView, greenView);NSDictionary *metricsV = NSDictionaryOfVariableBindings(margin, height);NSString *vflV = @"V:[greenView]-margin-[redView(height)]";NSArray *constraintV = [NSLayoutConstraint constraintsWithVisualFormat:vflVoptions:NSLayoutFormatAlignAllLeftmetrics:metricsVviews:viewsV];// 将约束添加到视图上[self.view addConstraints:constraintH];[self.view addConstraints:constraintV];
  • Swift

        // 使用 VFL 来创建约束数组public class func constraintsWithVisualFormat(format: String, options opts: NSLayoutFormatOptions, metrics: [String : AnyObject]?, views: [String : AnyObject]) -> [NSLayoutConstraint]参数:format  :VFL 语句opts    :约束类型metrics :约束值views   :需要设置约束的控件NSLayoutFormatOptions 约束类型:public static var AlignAllLeft: NSLayoutFormatOptions { get }               左边缘对齐public static var AlignAllRight: NSLayoutFormatOptions { get }              右边缘对齐public static var AlignAllTop: NSLayoutFormatOptions { get }                上边缘对齐public static var AlignAllBottom: NSLayoutFormatOptions { get }             下边缘对齐public static var AlignAllLeading: NSLayoutFormatOptions { get }            前边缘对齐public static var AlignAllTrailing: NSLayoutFormatOptions { get }           后边缘对齐public static var AlignAllCenterX: NSLayoutFormatOptions { get }            水平中心对齐public static var AlignAllCenterY: NSLayoutFormatOptions { get }            垂直中心对齐public static var AlignAllBaseline: NSLayoutFormatOptions { get }           文本底标线对齐public static var AlignAllLastBaseline: NSLayoutFormatOptions { get }       文本底标线对齐@available(iOS 8.0, *)public static var AlignAllFirstBaseline: NSLayoutFormatOptions { get }      文本上标线对齐public static var AlignmentMask: NSLayoutFormatOptions { get }              无对齐/* choose only one of these three*/public static var DirectionLeadingToTrailing: NSLayoutFormatOptions { get } 由前到后方向,默认public static var DirectionLeftToRight: NSLayoutFormatOptions { get }       由左到右方向public static var DirectionRightToLeft: NSLayoutFormatOptions { get }       由右到左方向public static var DirectionMask: NSLayoutFormatOptions { get }              无方向// 生成 views 和 metrics 参数["redView":redView]
        // 约束值let margin:NSNumber = 50let width:NSNumber = 100let height:NSNumber = 50// 创建水平方向约束/*redView 的宽度为 100kNilOptions = 0*/let viewsH = ["redView":redView]let metricsH = ["width":width]let vflH = "H:[redView(width)]"let constraintH = NSLayoutConstraint.constraintsWithVisualFormat( vflH,options: .AlignmentMask,metrics: metricsH,views: viewsH)// 创建垂直方向约束/*redView 的上边缘等于 greenView 的上边缘加 100(greenView 的高度为 50)redView 与 greenView 的左边缘对齐redView 的高度等于 50*/let viewsV = ["redView":redView, "greenView":greenView]let metricsV = ["margin":margin, "height":height]let vflV = "V:[greenView]-margin-[redView(height)]"let constraintV = NSLayoutConstraint.constraintsWithVisualFormat( vflV,options: .AlignAllLeft,metrics: metricsV,views: viewsV)// 将约束添加到视图上self.view.addConstraints(constraintH)self.view.addConstraints(constraintV)

2.5 Masonry 框架方式添加约束

2.5.1 Masonry 简介

  • Masonry 是目前最流行的 Autolayout 第三方框架,用优雅的代码方式编写 Autolayout,省去了苹果官方复杂的 Autolayout 代码,大大提高了开发效率。

  • mas_equalTo 和 equalTo:

    • 默认情况下 mas_equalTo 有自动包装功能,比如自动将 20 包装为 @20,equalTo 没有自动包装功能。如果添加了下面的宏,那么 mas_equalToequalTo 就没有区别,这个宏一定要添加到 #import "Masonry.h" 前面。

          // define this constant if you want to enable auto-boxing for default syntax#define MAS_SHORTHAND_GLOBALS
  • mas_width 和 width:

    • 默认情况下 width 是 make 对象的一个属性,用来添加宽度约束用的,表示对宽度进行约束。mas_width 是一个属性值,用来当做 equalTo 的参数,表示某个控件的宽度属性。如果添加了下面的宏,mas_width 也可以写成 width,就不用带 mas_ 前缀,这个宏一定要添加到 #import "Masonry.h" 前面。

          // define this constant if you want to use Masonry without the 'mas_' prefix#define MAS_SHORTHAND
    • mas_heightmas_centerX 以此类推。

  • 常用约束的类型:

        尺寸  :width\height\size边界  :left\leading\right\trailing\top\bottom中心点:center\centerX\centerY边界  :edges
  • 添加约束的方法:

        // 添加新的约束[view makeConstraints:^(MASConstraintMaker *make) {}];// 删掉以前的所有约束,添加新的约束[view remakeConstraints:^(MASConstraintMaker *make) {}];// 覆盖以前的某些特定的约束[view updateConstraints:^(MASConstraintMaker *make) {}];
  • 可有可无的用法:

    • 以下方法都仅仅是为了提高可读性,可有可无。

          - (MASConstraint *)with {return self;}- (MASConstraint *)and {return self;}

2.5.2 Masonry 的添加

  • Github 网址:https://github.com/SnapKit/Masonry

  • Masonry 使用 ARC

  • Masonry 使用步骤:

    • 添加 Masonry 文件夹的所有源代码到项目中。
    • 添加 2 个宏、添加主头文件,主头文件一定要放在宏定义的后面。

    • 不需要设置 translatesAutoresizingMaskIntoConstraints 的值。

  • Objective-C

        // 添加第三方库文件Masonry// 添加宏定义#define MAS_SHORTHAND#define MAS_SHORTHAND_GLOBALS// 包含头文件#import "Masonry.h"

2.5.3 Masonry 基本使用

  • Objective-C

        // 添加控件UIView *greenView = UIView.new;greenView.backgroundColor = UIColor.greenColor;[self.view addSubview:greenView];UIView *redView = UIView.new;redView.backgroundColor = UIColor.redColor;[self.view addSubview:redView];UIView *blueView = UIView.new;blueView.backgroundColor = UIColor.blueColor;[self.view addSubview:blueView];UIView *superview = self.view;// 约束值int padding = 10;// 添加约束[greenView makeConstraints:^(MASConstraintMaker *make) {make.top.greaterThanOrEqualTo(superview.top).offset(padding);make.left.equalTo(superview.left).offset(padding);make.bottom.equalTo(blueView.top).offset(-padding);make.right.equalTo(redView.left).offset(-padding);make.width.equalTo(redView.width);make.height.equalTo(redView.height);make.height.equalTo(blueView.height);}];[redView mas_makeConstraints:^(MASConstraintMaker *make) {make.top.equalTo(superview.mas_top).with.offset(padding);           // with withmake.left.equalTo(greenView.mas_right).offset(padding);             // without withmake.bottom.equalTo(blueView.mas_top).offset(-padding);make.right.equalTo(superview.mas_right).offset(-padding);make.width.equalTo(greenView.mas_width);make.height.equalTo(@[greenView, blueView]);                        // can pass array of views}];[blueView mas_makeConstraints:^(MASConstraintMaker *make) {make.top.equalTo(greenView.mas_bottom).offset(padding);make.left.equalTo(superview.mas_left).offset(padding);make.bottom.equalTo(superview.mas_bottom).offset(-padding);make.right.equalTo(superview.mas_right).offset(-padding);make.height.equalTo(@[greenView.mas_height, redView.mas_height]);   // can pass array of attributes}];
  • 运行效果

3、AutoLayout 动画效果设置

  • Objective-C

        // 添加动画效果[UIView animateWithDuration:2 animations:^{// 设置约束值/*设置约束的语句也可以写在此 block 之外,效果一样*/self.redViewWidthConstraint.constant = 100.0;// 对 AutoLayout 约束添加动画效果/*self.view 为添加了约束控件的父控件*/[self.view layoutIfNeeded];}];
  • Swift

        // 添加动画效果UIView.animateWithDuration(2) { // 设置约束值/*设置约束的语句也可以写在此 block 之外,效果一样*/self.redViewWidthConstraint.constant = 100.0// 对 AutoLayout 约束添加动画效果/*self.view 为添加了约束控件的父控件*/self.view.layoutIfNeeded()}

4、AutoLayout UILabel 设置效果

  • 在没有设置 Autolayout 时,UILabel 的文字内容总是居中显示,导致顶部和底部会有一大片空缺区域。

  • 设置 Autolayout(位置约束和宽度约束)后,UILabel 的 bounds 默认会自动包住所有的文字内容,顶部和底部不再会有空缺区域。

  • 设置宽度约束为小于等于某个值,Label 的文字较短时,Label 的宽度也会随着缩小。

转载于:https://www.cnblogs.com/QianChia/p/5759440.html

iOS - AutoLayout相关推荐

  1. iOS AutoLayout使用技巧

    关于ContentCompressionResistance, ContentHugging运用 如下图效果图,两个Label并列在同一排上,左边label自适应,右边label(红色)要使得内容全部 ...

  2. iOS Autolayout笔记

    一.Autolayout笔记 上午: 第一节 1.PPT介绍页面布局的三个时期 2.Autosizing简单使用1如何固定控件和四周的距离>讲解如何开启Autosizing (去掉Use Aut ...

  3. iOS autolayout

    http://blog.csdn.net/dizzthxl/article/details/9009537              (基本用法) http://blog.csdn.net/ysy44 ...

  4. iOS autolayout 约束冲突添加symbol breakpoint

    UIViewAlertForUnsatisfiableConstraints

  5. ios charts显示固定个数_上次挂在了百度iOS二面不服气, 三月之期已到,这次终于拿下offer!...

    笔试.面试题 1.算法题 (1).请在1000万个整型数据中以最快的速度找出其中最大的1000个数? 这是一个经常被问到的问题,百度网上解法也很多. 这里仅提供基本思路,供参考:把1000万的整型平均 ...

  6. Android和IOS的区别和联系

    关于开发语言的历史可以参看:计算机和编程语言的发展历史 关于Android和IOS的发展历史可以参看:Android和IOS的发展历史 开发语言不同 1.IOS使用的是ObjectC和Swift 2. ...

  7. iOS 强大第三方资源库

    Github用法 git-recipesGit recipes in Chinese. 高质量的Git中文教程. lark怎样在Github上面贡献代码 my-git有关 git 的学习资料 giti ...

  8. 技术周刊 Vol.7 - 【iOS丨好好学习,从娃抓起~】

    优质阅读感受及更多讨论,请查看原文: https://segmentfault.com/a/1190000007021303 我有一程序员朋友阿温,92 年,高个子,体型偏瘦,平时不善言辞,比较低调. ...

  9. SegmentFault 技术周刊 Vol.7 - iOS丨好好学习,从娃抓起~

    我有一程序员朋友阿温,92 年,高个子,体型偏瘦,平时不善言辞,比较低调.最近,阿温家小娃出生,让他当了一回公司的热议人物. 事情是这样的,那会儿大家都还在睡午觉,只听阿温一声猝不及防的喊声,接下来便 ...

最新文章

  1. Python3爬虫知识点总结
  2. 【BZOJ3512】DZY Loves Math IV(杜教筛)
  3. 【华为云技术分享】“技术-经济范式”视角下的开源软件演进剖析-part 1
  4. hdu 6015 Gameia(树上博弈)
  5. dumpsys gfxinfo packacges计算帧率
  6. 我的Python之路:浏览器模拟
  7. python数据结构5 - 排序与搜索
  8. 计算机二级c语言编译题评分,计算机二级C语言题型和评分标准
  9. 网络开盘选房微信抢房软件下载及使用教程
  10. freenas 11.2踩过的坑
  11. 【Js】JavaScript数据类型隐式转换
  12. 《java程序设计基础》使用Reader和Writer流类
  13. precede和previous_构词法词缀
  14. 2020-02-08
  15. 手机怎么用外嵌字幕_剪映教程大全:剪映加字幕、设置封面、变速等教程详解!...
  16. 【期末复习】操作系统
  17. HTML+CSS+JavaScript实现网页广告
  18. 计算机软件专业可以考哪些证书
  19. CSDN-markdown语法之如何使用LaTeX语法编写数学公式
  20. 极速office(Word)文字如何竖向

热门文章

  1. 深度学习与TensorFlow:VGG论文复现
  2. ElasticSearch优化系列三:索引过程
  3. 数据预处理 | 机器学习之特征工程
  4. 解决安卓SDK无法下载Package的问题
  5. mysql efbbbf_MySQL中修理特殊不可见uft8字符 - trim
  6. 二叉树线索化示意图_二叉树的线索化
  7. mysql 插入 point_mysq Point类型 查询和插入操作:insert和select
  8. CentOS 7如何配置yum源
  9. 手把手教你IDEA使用GIT进行项目管理
  10. mysql视图转sql server视图_SQL Sever MYSQL 视图实现的 2 种方式