swift开源框架SnapKit之ConstraintAttributes篇

ConstraintAttributes篇

ConstraintAttributes结构体

结构体定义如下:

internal struct ConstraintAttributes: OptionSetType, BooleanType 

一, 协议描述

ConstraintAttributes结构体实现了OptionSetType, BooleanType协议,这两个协议会继承其他的协议,其他协议不做介绍。有兴趣的同学可以点进源码查看。

OptionSetType协议

实现者可以增加如下功能:

  • 类似位运算能力:
Widtn.rawValue | Height.rawValue == Size.rawValue
// 按位或  1<<6 |  1<<7  == 二进制表示为11000000
  • 交集,并集,子集等系列数学处理功能.(我描述的不太准确):
    例如在本结构体中的出现的应用点
    internal var layoutAttributes:[NSLayoutAttribute] {
        var attrs = [NSLayoutAttribute]()
        //contains 解释为包含,个人理解: "&"(按位与)后值不等于0则为True,反之
        //方法定义在是OptionSetType协议的扩展中
        if (self.contains(ConstraintAttributes.Left)) {
            attrs.append(.Left)
        }
        //..........
        return attrs
      }
//重写运算符
internal func +=(inout left: ConstraintAttributes, right: ConstraintAttributes) {
    //unionInPlace 解释为合并 个人理解:取"|"(按位或)后的值
    //unionInPlace定义在OptionSetType协议的扩展中
    left.unionInPlace(right)
}
internal func -=(inout left: ConstraintAttributes, right: ConstraintAttributes) {
    //subtractInPlace 解释为去除 个人理解:取"^"(按位异或)后的值
    //subtractInPlace定义在OptionSetType协议的上级协议中
    left.subtractInPlace(right)
}
  • 原始值(rawValue)转换的能力
    本结构体实例话后会对应rawValue , 在对该实例进行操作时,其实也是操作对应的rawValue。例如:
    internal var layoutAttributes:[NSLayoutAttribute] {
        var attrs = [NSLayoutAttribute]()
        //操作ConstraintAttributes.Left实例其实就是操作对应的rawValue
        if (self.contains(ConstraintAttributes.Left)) {
            attrs.append(.Left)
        }
        //..........
        return attrs
      }
BooleanType协议

实现者可直接进行bool判断,例如在while , if 中

class BoolDemo: BooleanType{

    var boolValue: Bool { return true  } //实现协议属性
}

var bo = BoolDemo()

if(bo){
    print("bo为true") //会输出打印结果
}

二, 大量的static实例变量是啥

本结构体中定义了大量的静态实例变量,get方法返回的都是”self”(很重要,返回的都是ConstraintAttributes类型实例,对应的rawValue不同)。这些实例变量是框架的基本粒子,在其他模块中会大量用到,所以声明为static,确保其一直存在(生命周期是一直存在?)。

    internal static var None: ConstraintAttributes { return self.init(0) }
    internal static var Left: ConstraintAttributes { return self.init(1) }
    internal static var Top: ConstraintAttributes {  return self.init(2) }
    internal static var Right: ConstraintAttributes { return self.init(4) }
    internal static var Bottom: ConstraintAttributes { return self.init(8) }
    internal static var Leading: ConstraintAttributes { return self.init(16) }
    internal static var Trailing: ConstraintAttributes { return self.init(32) }
    internal static var Width: ConstraintAttributes { return self.init(64) }
    internal static var Height: ConstraintAttributes { return self.init(128) }
    //其他的就不粘了

这些实例变量与苹果原生的NSLayoutAttribute枚举一一对应。

public enum NSLayoutAttribute : Int {

    case Left
    case Right
    case Top
    case Bottom
    case Leading
    case Trailing
    case Width
    public static var LastBaseline: NSLayoutAttribute { get }
    @available(iOS 8.0, *)
    case TrailingMargin
    @available(iOS 8.0, *)
    case CenterXWithinMargins
    @available(iOS 8.0, *)
    case CenterYWithinMargins
    case NotAnAttribute
    //略了很多
}

还会多出如下实例变量。

    internal static var Size: ConstraintAttributes { return self.init(192) }
    internal static var Edges: ConstraintAttributes { return self.init(15) }
    internal static var Center: ConstraintAttributes { return self.init(768) }
    @available(iOS 8.0, *)
    internal static var Margins: ConstraintAttributes { return self.init(61440) }
    @available(iOS 8.0, *)
    internal static var CenterWithinMargins: ConstraintAttributes { return self.init(786432) }

这些额外的实例变量在原生的NSLayoutAttribute枚举中是没有的,这也是SnapKit优秀的功能点。每一个额外的实例变量可以拆分成多个”与原生的NSLayoutAttribute枚举值相对应的实例变量”的组合。例如

  • Size由Width和Height组合而成, Width的rawValue为Uint类型64(1<<6),Height的原始值定义为Uint类型128(1<<7) , (1<<6) | (1<<7) 按位或后二进制表示为11000000 也就是Uint类型192,192是Size的rawValue。
  • Edges由Left,Right,Top,Bottom构成 Edges=Left | Right | Top | Bottom。
  • Center和Margins,CenterWithMargins 同样适用。

三, 其他

layoutAttributes数组:
layoutAttributes数组的get方法 会先判断最后的rawValue值具体包含哪些ConstraintAttributes实例,并将这些ConstraintAttributes实例相对应的原生NSLayoutAttribute枚举类型保存到数组并返还。 最后的get到的值是构建原生NSLayoutConstraint所需参数。

    internal var layoutAttributes:[NSLayoutAttribute] {
        var attrs = [NSLayoutAttribute]()
        if (self.contains(ConstraintAttributes.Left)) {
            attrs.append(.Left)
        }
        if (self.contains(ConstraintAttributes.Top)) {
            attrs.append(.Top)
        }
        if (self.contains(ConstraintAttributes.Right)) {
            attrs.append(.Right)
        }
        if (self.contains(ConstraintAttributes.Bottom)) {
            attrs.append(.Bottom)
        }
        if (self.contains(ConstraintAttributes.Leading)) {
            attrs.append(.Leading)
        }
        if (self.contains(ConstraintAttributes.Trailing)) {
            attrs.append(.Trailing)
        }
        //.......................        
        return attrs
 }

框架关系中的角色:

本结构体(ConstraintAttributes)在整个框架中用于构建ConstraintItem实例。在其他模块中大量引用到。

调用指南

 make.width.height.equalTo(50)

这段代码的.width(不要忽略”点”)和.height都会”调用”对应的Width,Height的实例,在执行过程中两者会进行+=操作(上面有重写+=运算符的代码),最后返还的是Size的rawValue值,Size包含了两者。

// "snp_topLayoutGuideTop""snp_height" 同样会分别调用"Top","Height"实例
make.top.equalTo(snp_topLayoutGuideTop)
make.width.equalTo(otherView.snp_height)

与构建 “原生NSLayoutConstraint ”对应位置关系:

public convenience init(
item view1: AnyObject,
attribute attr1: NSLayoutAttribute,
relatedBy relation: NSLayoutRelation,
attribute attr2: NSLayoutAttribute,
constant c: CGFloat)

对应原生构造方法中NSLayoutAttribute类型的参数。
注意!一个按位或后的rawValue会对应多个NSLayoutAttribute对象(例如Size对应Left和Right)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值