Last active
March 6, 2018 15:38
Revisions
-
LinusU revised this gist
Mar 6, 2018 . 1 changed file with 39 additions and 32 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -6,20 +6,23 @@ import PlaygroundSupport /********************************************** * Library Types * **********************************************/ protocol REElement { func render() -> REElement? func toNativeView() -> UIView? } class REComponent<Props>: REElement { var children: [REElement] var props: [Props] var state: Any? init(_ props: [Props], _ children: [REElement] = []) { self.props = props self.children = children self.state = nil } func render() -> REElement? { return nil } func toNativeView() -> UIView? { return nil } } @@ -28,42 +31,46 @@ class REComponent { /********************************************** * Built-in components * **********************************************/ enum RELabelProps { case backgroundColor(UIColor) case text(String) case textColor(UIColor) } class RELabel: REComponent<RELabelProps> { override func toNativeView() -> UIView? { let view = UILabel() for prop in props { switch prop { case .backgroundColor(let value): view.backgroundColor = value case .text(let value): view.text = value case .textColor(let value): view.textColor = value } } return view } } enum REStackProps { case alignment(UIStackViewAlignment) case axis(UILayoutConstraintAxis) case distribution(UIStackViewDistribution) } class REStack: REComponent<REStackProps> { override func toNativeView() -> UIView? { let view = UIStackView() view.frame = CGRect(x: 0, y: 0, width: 200, height: 200) for prop in props { switch prop { case .alignment(let value): view.alignment = value case .axis(let value): view.axis = value case .distribution(let value): view.distribution = value } } for child in children { @@ -79,7 +86,7 @@ class REStack: REComponent { /********************************************** * Rendering function * **********************************************/ func RE_render(node: REElement, toTargetView targetView: UIView) { if let view = node.toNativeView() { if let stackedView = targetView as? UIStackView { stackedView.addArrangedSubview(view) @@ -105,9 +112,9 @@ class MyViewController : UIViewController { let view = UIView() view.backgroundColor = .white let tree = REStack([.alignment(.center)], [ RELabel([.backgroundColor(.cyan), .text("Hello:")]), RELabel([.textColor(.blue), .text("World!")]) ]) RE_render(node: tree, toTargetView: view) -
LinusU created this gist
Mar 6, 2018 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,120 @@ import UIKit import PlaygroundSupport /********************************************** * Library Types * **********************************************/ typealias REProps = [String: Any] class REComponent { var children: [REComponent] var props: REProps var state: Any? required init(_ props: REProps, _ children: [REComponent] = []) { self.props = props self.children = children self.state = nil } func render() -> REComponent? { return nil } func toNativeView() -> UIView? { return nil } } /********************************************** * Built-in components * **********************************************/ class RELabel: REComponent { override func toNativeView() -> UIView? { let view = UILabel() if props["backgroundColor"] != nil { view.backgroundColor = (props["backgroundColor"] as! UIColor) } if props["text"] != nil { view.text = (props["text"] as! String) } if props["textColor"] != nil { view.textColor = (props["textColor"] as! UIColor) } return view } } class REStack: REComponent { override func toNativeView() -> UIView? { let view = UIStackView() view.frame = CGRect(x: 0, y: 0, width: 200, height: 200) if props["alignment"] != nil { view.alignment = (props["alignment"] as! UIStackViewAlignment) } if props["axis"] != nil { view.axis = (props["axis"] as! UILayoutConstraintAxis) } if props["distribution"] != nil { view.distribution = (props["distribution"] as! UIStackViewDistribution) } for child in children { RE_render(node: child, toTargetView: view) } return view } } /********************************************** * Rendering function * **********************************************/ func RE_render(node: REComponent, toTargetView targetView: UIView) { if let view = node.toNativeView() { if let stackedView = targetView as? UIStackView { stackedView.addArrangedSubview(view) } else { targetView.addSubview(view) } return } if let child = node.render() { RE_render(node: child, toTargetView: targetView) return } } /********************************************** * User code * **********************************************/ class MyViewController : UIViewController { override func loadView() { let view = UIView() view.backgroundColor = .white let tree = REStack(["alignment": UIStackViewAlignment.center], [ RELabel(["backgroundColor": UIColor.cyan, "text": "Hello:"]), RELabel(["textColor": UIColor.blue, "text": "World!"]) ]) RE_render(node: tree, toTargetView: view) self.view = view } } // Present the view controller in the Live View window PlaygroundPage.current.liveView = MyViewController()