Skip to content

Instantly share code, notes, and snippets.

@djbe
Last active August 27, 2020 04:22
Show Gist options
  • Save djbe/3bdb403363ed446240c24b3dfe2c1c66 to your computer and use it in GitHub Desktop.
Save djbe/3bdb403363ed446240c24b3dfe2c1c66 to your computer and use it in GitHub Desktop.
SwiftGen template for Lottie animations
// Generated using SwiftGen — https://github.com/SwiftGen/SwiftGen
{% if files %}
{% set accessModifier %}{% if param.publicAccess %}public{% else %}internal{% endif %}{% endset %}
{% set documentPrefix %}{{param.documentName|default:"Document"}}{% endset %}
import Lottie
import UIKit
// swiftlint:disable superfluous_disable_command
// swiftlint:disable file_length
// MARK: - Lottie Animations
{% macro fileBlock file %}
{% for layer in file.documents.first.data.layers %}
{% call layerBlock layer %}
{% endfor %}
{% endmacro %}
{% macro layerBlock data %}
{% set shapesEnumName %}_{{ data.nm|swiftIdentifier:"pretty"|escapeReservedKeywords }}Shapes{% endset %}
{% set hasShapes %}{% for shape in data.shapes where shape.nm %}1{% endfor %}{% endset %}
{{accessModifier}} enum {{shapesEnumName}}{% if hasShapes %}: String{% endif %} {
{% for shape in data.shapes where shape.nm %}
case {{ shape.nm|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords }} = "{{shape.nm}}"
{% endfor %}
}
{{accessModifier}} static let {{ data.nm|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords }} = LottieLayer("{{ data.nm }}", {{shapesEnumName}}.self)
{% endmacro %}
// swiftlint:disable identifier_name line_length number_separator type_body_length
{{accessModifier}} enum LottieFile: String {
{% for file in files %}
case {{file.documents.first.data.nm|swiftIdentifier:"pretty"|lowerFirstWord|escapeReservedKeywords}} = "{{file.name}}.json"
{% endfor %}
}
{{accessModifier}} enum Lottie {
{% for file in files %}
{{accessModifier}} enum {{file.documents.first.data.nm|swiftIdentifier:"pretty"|escapeReservedKeywords}} {
{% filter indent:2 %}{% call fileBlock file %}{% endfilter %}
}
{% endfor %}
}
// swiftlint:enable identifier_name line_length number_separator type_body_length
// MARK: - Implementation Details
{{accessModifier}} protocol LottieConfigurable {
var path: String { get }
}
{{accessModifier}} struct LottieLayer<T>: LottieConfigurable {
let name: String
init(_ name: String, _ shapesType: T.Type) {
self.name = name
}
var path: String {
return name
}
}
extension LottieLayer where T: RawRepresentable, T.RawValue == String {
subscript(shape: T) -> LottieShape {
return LottieShape(layer: name, name: shape.rawValue)
}
}
{{accessModifier}} struct LottieShape: LottieConfigurable {
let layer: String
let name: String
var path: String {
return "\(layer).\(name)"
}
}
extension LOTAnimationView {
convenience init(file: LottieFile, bundle: Bundle = .main) {
self.init(name: file.rawValue, bundle: bundle)
}
func setFill(color: UIColor) {
setDelegate(color: color, path: nil, name: "Fill")
}
func setFill(color: UIColor, for item: LottieConfigurable) {
setDelegate(color: color, path: item.path, name: "Fill")
}
func setOutline(color: UIColor) {
setDelegate(color: color, path: nil, name: "Path")
}
func setOutline(color: UIColor, for item: LottieConfigurable) {
setDelegate(color: color, path: item.path, name: "Path")
}
private static var lottieDelegatesKey: Int = 0
private func setDelegate(color: UIColor, path: String?, name: String) {
var delegates = objc_getAssociatedObject(self, &LOTAnimationView.lottieDelegatesKey) as? [String: LOTColorValueCallback] ?? [:]
let callback = LOTColorValueCallback(color: color.cgColor)
for i in 1..<10 {
let path = [path, "**", "\(name) \(i)", "Color"].compactMap { $0 }.joined(separator: ".")
let keyPath = LOTKeypath(string: path)
setValueDelegate(callback, for: keyPath)
delegates[path] = callback
}
objc_setAssociatedObject(self, &LOTAnimationView.lottieDelegatesKey, delegates, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
{% else %}
// No files found
{% endif %}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment