13、在IB中使用Auto Layout

在frame系统中,最重要的就是尺寸和位置,通过设置View的frame属性来表示它的位置和尺寸,从而确定布局。
Auto Layout是布局的另一种表示方法,这套布局系统中没有位置和尺寸,只有约束。添加的约束最终会被系统转化为frame。

1 最好不要在Auto Layout中设置frame

在Auto Layout中设置frame可能会导致设置无效。
AutoLayout系统有别于frame系统,当一个控件使用了Auto Layout,设置了必要的约束,此时在viewDidLoad中设置frame是无效的,只有把设置frame的代码放到viewDidLayoutSubviews方法才会生效,而且最好放在viewDidLayoutSubviews方法里面,先调用super.viewDidLayoutSubviews(),否则可能会出现某些未知的错误。

当一个View使用了Auto Layout布局,系统在layout subviews时会加载它的约束信息,通过约束信息布局这个View。其实通过viewDidLoad方法设置frame起了作用,但是由于layout subviews是在它的后面执行的,所以在viewDidLoad里面设置frame是无效的。但是可以在viewDidLayoutSubviews方法里面进行设置,因为此时layout subviews已经完成。

2 约束

2.1 Auto Layout的数学公式

item1.attribute1 = multiplier * item2.attribute2 + constant

在这个公式中,item1、item2是要布局的View;attribute1、attribute2是约束属性;"="是约束中的关系;multiplier和constant是调节这种关系的因子,是这种线性关系的常量。在通常情况下,multiplier是1.0。

创建一个约束实例

@available(iOS 6.0, *)
    public convenience init(item view1: Any, attribute attr1: NSLayoutConstraint.Attribute, relatedBy relation: NSLayoutConstraint.Relation, toItem view2: Any?, attribute attr2: NSLayoutConstraint.Attribute, multiplier: CGFloat, constant c: CGFloat)

设置一个约束:

let left = NSLayoutConstraint(item: aSubView, attribute: .left, relatedBy: .equal, toItem: aSuperView, attribute: .left, multiplier: 1.0, constant: 100)

AutoLayout是靠约束来描述两个View之间的关系的,这个View必须是兄弟关系或者是父子关系。

2.2 约束属性

 public enum Attribute : Int {

        
        case left = 1

        case right = 2

        case top = 3

        case bottom = 4

        case leading = 5

        case trailing = 6

        case width = 7

        case height = 8

        case centerX = 9

        case centerY = 10

        case lastBaseline = 11

        
        @available(iOS 8.0, *)
        case firstBaseline = 12

        
        @available(iOS 8.0, *)
        case leftMargin = 13

        @available(iOS 8.0, *)
        case rightMargin = 14

        @available(iOS 8.0, *)
        case topMargin = 15

        @available(iOS 8.0, *)
        case bottomMargin = 16

        @available(iOS 8.0, *)
        case leadingMargin = 17

        @available(iOS 8.0, *)
        case trailingMargin = 18

        @available(iOS 8.0, *)
        case centerXWithinMargins = 19

        @available(iOS 8.0, *)
        case centerYWithinMargins = 20

        
        case notAnAttribute = 0
    }

约束属性是数学公式中的attribute1和attribute2,也是NSLayoutConstraint初始化方法中的attribute参数。

  • left与leading是相同的,right与trailing是相同的,leftMargin与leading Margins是相同的,rightMargin与right Margins是相同的。

  • 带Margin的属性是以Margin为参照系建立关系的,不带Margin的属性是以View本身为参照系建立关系的。通常来说,View都有自己的Margin,也就是边缘的留白,带Margin的属性在计算关系时计算的是Margin的边缘,不带Margin的属性在计算关系时计算的是View的边缘。

  • 带Baseline的属性是指以View里面的内容基准线为参照系建立关系的,因为通常来说View的边缘并不是它内容的边缘,带Baseline的case是以View内容的边缘来计算关系的,不带Baseline的case是以View的边缘来计算关系的。

2.3 约束关系

  public enum Relation : Int {

        
        case lessThanOrEqual = -1

        case equal = 0

        case greaterThanOrEqual = 1
    }

2.4 multiplier和constant

通常设置multiplier为1.0,一般只有在布局等分排列的时候才将multiplier设置为其他值,根据不同情况设置对应的constant的值,constant是调节布局关系时设置的最重要的值。

2.5 约束的创建和添加

创建:

let left = NSLayoutConstraint(item: aSubView, attribute: .left, relatedBy: .equal, toItem: aSuperView, attribute: .left, multiplier: 1.0, constant: 100)

addConstraint是指添加一个约束,addConstraints是指添加一个数组

2.6 约束的优先级

当设置的约束过多时就会可能引起约束之间的相互冲突。系统会随机选择其中一些约束来确定布局。
优先级对应的就是NSLayoutConstraint累中的priority属性,该属性的类型是UILayoutPriority,而UILayoutPriority是Float类型。

public typealias UILayoutPriority = Float

但是在实际应用中,priority设置的范围是1-1000,在IB中只能设置1-1000中的整数。
下面是几个常用的优先级:

public let UILayoutPriorityRequired: UILayoutPriority //1000

public let UILayoutPrioritDefaultHigh: UILayoutPriority //750

public let UILayoutPrioritDefaultLow: UILayoutPriority //250

public let UILayoutPrioritFittingSizeLevel: UILayoutPriority //250

UILayoutPriorityRequired是最高优先级,UILayoutPrioritDefaultHigh是压缩阻力的优先级,UILayoutPrioritDefaultLow是内容吸附的优先级,UILayoutPrioritFittingSizeLevel是内置的最低优先级

如果在6个约束中挑选4个约束,系统会挑选优先级最高的4个。如果优先级都相同,则会随机挑选4个。我们可以通过设置优先级来达到布局复杂UI的目的。

3 Auto Layout相关的菜单介绍

请添加图片描述

3.1 Update frames介绍

在IB中同时存在frame和Auto Layout两种布局体系。当添加约束确定与frame确定的布局冲突时,点击Update frames按钮可以自动改变frame,使其与Auto Layout确定的布局保持一致。

3.2 Embed in Stack介绍

3.3 Align介绍

3.4 Add New Constraints介绍

3.5 Resolve Auto Layout Issue介绍

4 Show the size inspector再介绍

4.1 Intrinsic Size --固有尺寸

所谓固有尺寸就是不需要设置width和height,系统可以通过它的内容属性自动获取大小。
无需设置尺寸的约束的视图有:

  • Label
  • Button
  • SegmentControl
  • TextField
  • Slider(无需确定高度,但是必须确定宽度)
  • Switch
  • ActivityIndicatorView
  • ProgressView(无需确定高度,但是需要确定宽度)
  • PageControl
  • Stepper
  • ImageView(当ImageView的实例显示图片且ImageView的size与图片的大小相同时)
  • DatePicker(无需确定高度,但是需要确定宽度)
  • PickerView(无需确定高度,但是需要确定宽度)

4.2 Content Compression Resistance – 压缩阻力

压缩阻力是指一个视图保护其内容完整性的能力,压缩阻力越大,该视图保护其内容完整性的能力越强,内容越不容被压缩或者裁剪。

4.3 Content Hugging – 内容吸附

内容吸附是指一个视图保持它的尺寸与其内容尺寸相匹配的能力,内容吸附能力越强,该视图保持她的尺寸和内容尺寸相一致的能力越强;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值