Skip to content

Instantly share code, notes, and snippets.

@fpg1503
Last active July 11, 2016 21:36
Show Gist options
  • Save fpg1503/cd25efb3ddf280811f914a78c4aebe1b to your computer and use it in GitHub Desktop.
Save fpg1503/cd25efb3ddf280811f914a78c4aebe1b to your computer and use it in GitHub Desktop.
ViewSpitter: Programmatic UIView Boilerplate generator
extension String {
mutating func appendLine(line: String = "") {
self += "\n\(line)"
}
mutating func appendMark(mark: String) {
self.appendLine()
self.appendLine("//MARK - \(mark)")
self.appendLine()
}
}
struct ViewModel: ArrayLiteralConvertible {
typealias Element = String
let name: String
let type: String
let style: String
let color: String
init(arrayLiteral elements: ViewModel.Element...) {
name = elements[0]
type = elements[1]
style = elements[2]
color = elements [3]
}
}
struct ClassModel {
let className: String
let superClass: String
let views: [ViewModel]
let viewRelations: [(String, String)]
}
extension ClassModel {
func generateBoilerplate() -> String {
// Header
var result = ""
result.appendLine("import UIKit")
result.appendLine("import Cartography")
result.appendLine()
result.appendLine("final class \(className): \(superClass) {")
//View declaration
for viewModel in views {
result.appendLine("private var \(viewModel.name): \(viewModel.type)? {")
result.appendLine("didSet {")
result.appendLine("guard let \(viewModel.name) = \(viewModel.name) where \(viewModel.name) != oldValue else { return }")
result.appendLine()
result.appendLine("\(viewModel.name).setStyle(.\(viewModel.style))")
result.appendLine("\(viewModel.name).textColor = .\(viewModel.color)Color()")
result.appendLine("addSubview(\(viewModel.name))")
result.appendLine("}")
result.appendLine("}")
result.appendLine()
}
//Designated initializer
result.appendMark("Designated initializer")
result.appendLine("required init?(coder aDecoder: NSCoder) {")
result.appendLine("super.init(coder: aDecoder)")
result.appendLine("setupViews()")
result.appendLine("}")
result.appendLine("}")
//Configuration
result.appendMark("Configuration")
result.appendLine("extension \(className) {")
result.appendLine("func configureWith(viewModel viewModel: Any) {")
result.appendLine("//FIXME: Replace me with ViewModel and implement me")
result.appendLine("}")
result.appendLine("}")
//Layout
result.appendMark("Layout")
result.appendLine("private extension \(className) {")
result.appendLine("private func setupViews() {")
for viewModel in views {
result.appendLine("\(viewModel.name) = \(viewModel.type)()")
}
result.appendLine("setupConstraints()")
result.appendLine("}")
result.appendLine()
result.appendLine("private func setupConstraints() {")
if let first = views.first {
var line = "guard let \(first.name) = \(first.name)"
let otherViews = Array(views.dropFirst())
if otherViews.count == 0 {
line += " else {"
result.appendLine(line)
} else {
line += ","
result.appendLine(line)
for (index, view) in otherViews.enumerate() {
var shadowing = "\(view.name) = \(view.name)"
shadowing += index == otherViews.count - 1 ? " else {" : ","
result.appendLine(shadowing)
}
}
result.appendLine("print(\"[WARNING]: Setting subviews failed\")")
result.appendLine("return")
result.appendLine("}")
}
result.appendLine()
if viewRelations.count > 0 {
result.appendLine("//TODO: Layout constraints")
result.appendLine()
for (first, second) in viewRelations {
let translatedFirst = first == "self" ? "view" : first
let translatedSecond = second == "self" ? "view" : second
result.appendLine("constrain(\(first), \(second)) { \(translatedFirst), \(translatedSecond) in")
result.appendLine("//FIXME: Add constraints")
result.appendLine("}")
result.appendLine()
}
} else if let first = views.first {
result.appendLine("/*")
result.appendLine("constrain(\(first.name), self) { \(first.name), view in")
result.appendLine("\(first.name).leading == view.leading + 20")
result.appendLine("\(first.name).top == view.top + 20")
result.appendLine("}")
result.appendLine("*/")
}
result.appendLine("}")
result.appendLine("}")
return result
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment