SnapKit 的那些事

2018-12-09  本文已影响39人  Lin__Chuan

SnapKit 是一款可在 iOS 和 OS X 上轻松实现 Auto Layout 的 DSL , 用 Swift 实现.
与之对应, Masonary 用 Objective-C 实现, 两个框架的作者均是 SnapKit 团队

这里有几点需要注意: (下面说的 AutoLayout 均为官方的布局技术, 不包括第三方的布局框架)

Auto Layout 的由来及使用

Auto Layout 是 Apple 提供的用于布局App页面的技术, 可以通过 Interface Builder 或者 纯代码 使用.

  1. 通过 StoryBoard / xib 可以轻松设计界面, 拖线布局页面, 适用于业务逻辑不是很复杂的项目.
  2. 通过 纯代码 使用 AutoLayout, 由于Apple的原始布局API比较繁琐, 所以诞生了SnapKit, Masonary 这两种框架.

下面是一个例子, view1是子页面, superView 是其父页面, 我们需要设置 view1 的内边距均为10.

由上面可以明显看出, SnapKit 框架通过包装原生布局 API , 极大的简化了API 的调用.

与 AutoLayout 相对的布局方式是 FrameLayout.

DSL 的由来及使用

DSL (Domain Specific Language), 特定领域下的语言, 即为了解决某些特定场景下的任务而专门设计的语言. 与 DSL 相对应的是 GPL (General programming language), 通用编程语言, 比如 C/C++/Objective-C/Swift 等.

DSL 的例子:

离开了为某一 DSL 专门开发的语言环境或者代码框架, DSL 是无法运行的.

SnapKit 源码分析

有几点需要说明

SnapKit 的源码启示

#if, #else, #endif, 可以用来控制编译流程和内容, os() 可以检测系统平台.
typealias, 可以为类起别名, 也可以实现跨平台

#if os(iOS) || os(tvOS)
    import UIKit
    #if swift(>=4.2)
        typealias LCLayoutRelation = NSLayoutConstraint.Relation
        typealias LCLayoutAttribute = NSLayoutConstraint.Attribute
    #else
        typealias LCLayoutRelation = NSLayoutRelation
        typealias LCLayoutAttribute = NSLayoutAttribute
    #endif
    typealias LCLayoutPriority = UILayoutPriority
#else
    import AppKit
    typealias LCLayoutRelation = NSLayoutConstraint.Relation
    typealias LCLayoutAttribute = NSLayoutConstraint.Attribute
    typealias LCLayoutPriority = NSLayoutConstraint.Priority
#endif

@available 用于函数、方法、类或协议的前面,表明平台和操作系统适用性.
* 表示全平台, deprecated:3.0, 表示版本号3.0开始过时, message:"", 表示消息内容.

@available(*, deprecated:3.0, message:"Use newer snp.* syntax.")
public var snp_left: ConstraintItem { return self.snp.left }

@available(iOS 9.0, *)  表示 iOS 9.0 开始适用
 fatalError("Cannot constraint to multiple non identical attributes. (\(file), \(line))");
public protocol LCConstraintRelatableTarget {
}

extension Int: LCConstraintRelatableTarget {
}

extension UInt: LCConstraintRelatableTarget {
}
internal func + (left: LCConstraintAttributes,
                 right: LCConstraintAttributes) -> LCConstraintAttributes {
    return left.union(right)
}

internal func +=(left: inout LCConstraintAttributes,
                 right: LCConstraintAttributes) {
    left.formUnion(right)
}

internal func -=(left: inout LCConstraintAttributes,
                 right: LCConstraintAttributes) {
    left.subtract(right)
}

internal func ==(left: LCConstraintAttributes,
                 right: LCConstraintAttributes) -> Bool {
    return left.rawValue == right.rawValue
}
struct Person: CustomStringConvertible {
    var name: String?
    
    var description: String {
        var desc = "<"
        desc += self.name ?? "lili"
        desc += ">"
        
        return desc
    }
}

参考
从 Auto Layout 的布局算法谈性能
深入理解 Autolayout 与列表性能 -- 背锅的 Cassowary 和偷懒的 CPU
谈谈 DSL 以及 DSL 的应用
动态界面:DSL&布局引擎

上一篇下一篇

猜你喜欢

热点阅读