Skip to content

Commit

Permalink
Make view controller declarative
Browse files Browse the repository at this point in the history
  • Loading branch information
MihaelIsaev committed Apr 17, 2020
1 parent a3e5820 commit 5bb8fd3
Show file tree
Hide file tree
Showing 5 changed files with 432 additions and 11 deletions.
5 changes: 1 addition & 4 deletions Classes/Controllers/FormViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,9 @@ open class FormViewController: ViewController {
public lazy var scrollView = ScrollView().edgesToSuperview(top: 0, leading: 0, trailing: 0).bottomToSuperview($bottom)
public lazy var stackView = VStack().edgesToSuperview().width(to: .width, of: scrollView)

@State
var bottom: CGFloat = 0

open override func buildUI() {
super.buildUI()
view.body { scrollView }
_view.body { scrollView }
scrollView.body { stackView }
$keyboardHeight.listen { height in
self.bottom = -1 * height
Expand Down
81 changes: 75 additions & 6 deletions Classes/Controllers/ViewController.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import Foundation
import UIKit

open class ViewController: UIViewController {
open class ViewController: UIViewController, DeclarativeProtocol, DeclarativeProtocolInternal, _Toucheable {
open override var preferredStatusBarStyle: UIStatusBarStyle { statusBarStyle.rawValue }
/// UIKitPlus reimplementation of `preferredStatusBarStyle`
open var statusBarStyle: StatusBarStyle { .default }

@State public var keyboardHeight: CGFloat = 0
open var statusBarStyle: StatusBarStyle { _statusBarStyle ?? .default }

public init (@ViewBuilder block: ViewBuilder.SingleView) {
super.init(nibName: nil, bundle: nil)
Expand Down Expand Up @@ -35,10 +33,71 @@ open class ViewController: UIViewController {
NotificationCenter.default.removeObserver(self)
}

open func buildUI() {
view.backgroundColor = .white
// MARK: DeclarativeProtocol

public var declarativeView: View { _view }
public lazy var properties = Properties<View>()
lazy var _properties = PropertiesInternal()

@State public var height: CGFloat = 0
@State public var width: CGFloat = 0
@State public var top: CGFloat = 0
@State public var leading: CGFloat = 0
@State public var left: CGFloat = 0
@State public var trailing: CGFloat = 0
@State public var right: CGFloat = 0
@State public var bottom: CGFloat = 0
@State public var centerX: CGFloat = 0
@State public var centerY: CGFloat = 0

var __height: State<CGFloat> { _height }
var __width: State<CGFloat> { _width }
var __top: State<CGFloat> { _top }
var __leading: State<CGFloat> { _leading }
var __left: State<CGFloat> { _left }
var __trailing: State<CGFloat> { _trailing }
var __right: State<CGFloat> { _right }
var __bottom: State<CGFloat> { _bottom }
var __centerX: State<CGFloat> { _centerX }
var __centerY: State<CGFloat> { _centerY }

lazy var _view = View().background(.white).edgesToSuperview()

open override func loadView() {
view = _view
}

// MARK: Toucheable

var _touchesBegan: TouchClosure?
var _touchesMoved: TouchClosure?
var _touchesEnded: TouchClosure?
var _touchesCancelled: TouchClosure?

override open func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
_touchesBegan?(touches, event)
}

open override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesMoved(touches, with: event)
_touchesMoved?(touches, event)
}

override open func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesEnded(touches, with: event)
_touchesEnded?(touches, event)
}

open override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesCancelled(touches, with: event)
_touchesCancelled?(touches, event)
}

// MARK: Lifecycle

open func buildUI() {}

public var isAppearedOnce = false

open override func viewDidAppear(_ animated: Bool) {
Expand All @@ -61,6 +120,8 @@ open class ViewController: UIViewController {

open func viewDidAppearFirstTime(_ animated: Bool) {}

@State public var keyboardHeight: CGFloat = 0

private var isSubscribedToKeyboardNotifications = false

private func subscribeToKeyboardNotifications() {
Expand Down Expand Up @@ -113,6 +174,14 @@ open class ViewController: UIViewController {
}
return self
}

var _statusBarStyle: StatusBarStyle?

@discardableResult
public func statusBarStyle(_ value: StatusBarStyle) -> Self {
_statusBarStyle = value
return self
}
}

// MARK: Keyboard Notifications
Expand Down
6 changes: 5 additions & 1 deletion Classes/Extensions/UIViewController+Body.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import UIKit

extension UIViewController {
open func body(@ViewBuilder block: ViewBuilder.SingleView) {
view.body { block().viewBuilderItems }
if let s = self as? ViewController {
s._view.body { block().viewBuilderItems }
} else {
view.body { block().viewBuilderItems }
}
}
}
66 changes: 66 additions & 0 deletions Classes/Protocols/BackgroundColorable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import UIKit

public protocol BackgroundColorable {
@discardableResult
func background(_ color: UIColor) -> Self

@discardableResult
func background(_ number: Int) -> Self

@discardableResult
func background(_ state: State<UIColor>) -> Self

@discardableResult
func background<V>(_ expressable: ExpressableState<V, UIColor>) -> Self

@discardableResult
func background(_ identifier: FontIdentifier, _ size: CGFloat) -> Self
}

protocol _BackgroundColorable: BackgroundColorable {
func _setBackgroundColor(_ v: UIColor)
}

extension BackgroundColorable {
@discardableResult
public func background(_ number: Int) -> Self {
background(number.color)
}

@discardableResult
public func background(_ state: State<UIColor>) -> Self {
background(state.wrappedValue)
state.listen {
self.background($0)
}
return self
}

@discardableResult
public func background<V>(_ expressable: ExpressableState<V, UIColor>) -> Self {
background(expressable.value())
expressable.state.listen {
self.background(expressable.value())
}
return self
}
}

@available(iOS 13.0, *)
extension BackgroundColorable {
@discardableResult
public func background(_ color: UIColor) -> Self {
guard let s = self as? _BackgroundColorable else { return self }
s._setBackgroundColor(color)
return self
}
}

// for iOS lower than 13
extension _BackgroundColorable {
@discardableResult
public func background(_ color: UIColor) -> Self {
_setBackgroundColor(color)
return self
}
}
Loading

0 comments on commit 5bb8fd3

Please sign in to comment.