SDCALayer

服务器驱动的 CALayer

演示

demo

文档

支持的图层

JSON 转 CALayer

let json: String = ""

let model = SDCALayer.load(fromJSON: json)

let layer: CALayer = model?.convertToLayer()

YAML 转 CALayer

let model = SDCALayer.load(fromYAML: yaml)

CALayer 转 JSON

let layer = CAShapeLayer()
/* ~ customize layer  ~ */

let model = SDCALayer(model: layer.codable())

let json: String = model?.json

CALayer 转 YAML

let yaml: String = model?.yaml

图层模型的格式

图层模型在以下目录中定义。模型

{
    "frame": [
        [
            0,
            0
        ],
        [
            100,
            50
        ]
    ],
    "cornerRadius": 5.0,
    "borderColor": {
        "code": "#FF0088"
    },
    // other properties
}

由于我们需要知道图层的实际类,我们需要接收一个包含类名称的模型以及每个类的模型,如下所示

{
    "class": "CAShapeLayer",
    "layerModel": {
        // CAShapeLayer Model
    }
}

通过使用 p-x9/IndirectlyCodable 库,CALayer 间接遵循 Codable 协议,允许与 json 进行互相转换。

支持自定义图层类

假设我们有以下自定义的图层类。

class AALayer: CALayer {
    var newProperty: String? = "AAAA"
}

像这样创建图层模型。

点击展开
class JAALayer: JCALayer {
    typealias Target = AALayer // alias for target layer class

    // Coding key (codable)
    private enum CodingKeys: String, CodingKey {
        case newProperty
    }

    // Target class name to exact layer class
    // You must specify the class name including the product name and package name.
    // (ex. MyApp.AALayer)
    public override class var targetTypeName: String {
        String(reflecting: Target.self)
    }

    override init() {
        super.init()
    }

    // Decodable
    public required init(from decoder: Decoder) throws {
        try super.init(from: decoder)

        let container = try decoder.container(keyedBy: CodingKeys.self)

        newProperty = try container.decodeIfPresent(String.self, forKey: .newProperty)
    }

    public required convenience init(with object: CALayer) {
        self.init()

        reverseApplyProperties(with: object)
    }

    // Encodable
    public override func encode(to encoder: Encoder) throws {
        try super.encode(to: encoder)

        var container = encoder.container(keyedBy: CodingKeys.self)

        try container.encode(newProperty, forKey: .newProperty)
    }

    // apply properties to taget from model
    // model -> target
    public override func applyProperties(to target: CALayer) {
        super.applyProperties(to: target)

        guard let target = target as? AALayer else { return }

        target.newProperty = newProperty
    }

    // apply properties to model from target
    // targe -> model
    public override func applyProperties(with target: CALayer) {
        super.applyProperties(with: target)

        guard let target = target as? AALayer else { return }

        newProperty = target.newProperty
    }

    public override func convertToLayer() -> CALayer? {
        let layer = AALayer()

        self.applyProperties(to: layer)

        return layer
    }
}

最后,在图层类扩展中指定模型类

extension AALayer {
    public typealias Target = JAALayer

    public override class var codableTypeName: String {
        String(reflecting: Target.self)
    }
}

示例

Websocket 热重载

启动服务器,更改 json,保存它,它将反映在应用程序中。安装 calayer-ws 应用 到你的 iphone(或模拟器)并连接你的服务器。

A B
A B
python ./server/ws-hotreload-server.py "<path to json>"

示例 json 文件在这里

python ./server/ws-hotreload-server.py "./Example/json/star.json"

许可

MIT 许可证