Created
October 16, 2018 14:36
-
-
Save alexdrone/3f1ef920f264c5cccdc39363c2aa94ed to your computer and use it in GitHub Desktop.
Vanilla View Swift
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 characters
import UIKit | |
/// Represents the internal state of the view. | |
public protocol BaseViewState { | |
init() | |
} | |
/// Empty view state. | |
public final class BaseViewNullState: BaseViewState { | |
public init() { | |
// No-op. | |
} | |
} | |
/// The properties passed down to the view. | |
public protocol BaseViewProps { | |
init() | |
} | |
/// Empty properties. | |
public final class BaseViewNullProps: BaseViewProps { | |
public init() { | |
// No-op. | |
} | |
} | |
public protocol BaseViewDelegate: AnyObject { } | |
public class BaseView< | |
StateType: BaseViewState, | |
PropsType: BaseViewProps>: UIView { | |
/// The view delegate. | |
public weak var delegate: BaseViewDelegate? | |
/// The view current state. | |
public private(set) var state = StateType() { | |
didSet { | |
onStateChange(old: oldValue, new: state) | |
} | |
} | |
/// The view properties. | |
public var props = PropsType() { | |
didSet { | |
onPropsChange(old: oldValue, new: props) | |
} | |
} | |
public override init(frame: CGRect) { | |
super.init(frame: frame) | |
initSubviews() | |
} | |
public required init?(coder aDecoder: NSCoder) { | |
super.init(coder: aDecoder) | |
initSubviews() | |
} | |
/// Initialize all of the subviews. | |
open func initSubviews() { | |
// Subviews configuration code here. | |
} | |
/// The `props` member changed. | |
/// - note: Subviews to override this method if necessary, the default implementation triggers | |
/// `setNeedsLayout`. | |
open func onPropsChange(old: PropsType, new: PropsType) { | |
// Subviews to override this method if necessary. | |
setNeedsLayout() | |
} | |
/// The `props` member changed. | |
/// - note: Subviews to override this method if necessary, the default implementation triggers | |
/// `setNeedsLayout`. | |
open func onStateChange(old: StateType, new: StateType) { | |
// Subviews to override this method if necessary. | |
setNeedsLayout() | |
} | |
} | |
public extension UIResponder { | |
/// Returns the parent view controller for this `UIResponder`. | |
public func viewControllerForAncestor() -> UIViewController? { | |
if self.next is UIViewController { | |
return self.next as? UIViewController | |
} else { | |
if self.next != nil { | |
return (self.next!).viewControllerForAncestor() | |
} | |
else {return nil} | |
} | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment