Skip to content

Commit

Permalink
Add view controller support to hierarchy and layout
Browse files Browse the repository at this point in the history
  • Loading branch information
andyfinnell committed Oct 2, 2020
1 parent dfba949 commit fa7a3e1
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 43 deletions.
86 changes: 43 additions & 43 deletions Sources/ViewKit/Layout/Layout.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ public enum HorizontalAnchor {
case leadingGuide
case trailingGuide
case centerGuide
case leading(NativeView)
case trailing(NativeView)
case center(NativeView)
case leading(NativeViewable)
case trailing(NativeViewable)
case center(NativeViewable)

fileprivate func lower(other: HorizontalAnchor) -> LayoutAssemblyHAnchor {
switch self {
Expand All @@ -26,11 +26,11 @@ public enum HorizontalAnchor {
}
return LayoutAssemblyHAnchor(item: s, attribute: .hcenter)
case let .leading(view):
return LayoutAssemblyHAnchor(item: view, attribute: .leading)
return LayoutAssemblyHAnchor(item: view.asView, attribute: .leading)
case let .trailing(view):
return LayoutAssemblyHAnchor(item: view, attribute: .trailing)
return LayoutAssemblyHAnchor(item: view.asView, attribute: .trailing)
case let .center(view):
return LayoutAssemblyHAnchor(item: view, attribute: .hcenter)
return LayoutAssemblyHAnchor(item: view.asView, attribute: .hcenter)
}
}

Expand All @@ -39,9 +39,9 @@ public enum HorizontalAnchor {
case .leadingGuide: return nil
case .trailingGuide: return nil
case .centerGuide: return nil
case let .leading(view): return view
case let .trailing(view): return view
case let .center(view): return view
case let .leading(view): return view.asView
case let .trailing(view): return view.asView
case let .center(view): return view.asView
}
}
}
Expand All @@ -50,10 +50,10 @@ public enum VerticalAnchor {
case topGuide
case bottomGuide
case centerGuide
case top(NativeView)
case bottom(NativeView)
case baseline(NativeView)
case center(NativeView)
case top(NativeViewable)
case bottom(NativeViewable)
case baseline(NativeViewable)
case center(NativeViewable)

fileprivate func lower(other: VerticalAnchor) -> LayoutAssemblyVAnchor {
switch self {
Expand All @@ -73,13 +73,13 @@ public enum VerticalAnchor {
}
return LayoutAssemblyVAnchor(item: s, attribute: .vcenter)
case let .top(view):
return LayoutAssemblyVAnchor(item: view, attribute: .top)
return LayoutAssemblyVAnchor(item: view.asView, attribute: .top)
case let .bottom(view):
return LayoutAssemblyVAnchor(item: view, attribute: .bottom)
return LayoutAssemblyVAnchor(item: view.asView, attribute: .bottom)
case let .baseline(view):
return LayoutAssemblyVAnchor(item: view, attribute: .baseline)
return LayoutAssemblyVAnchor(item: view.asView, attribute: .baseline)
case let .center(view):
return LayoutAssemblyVAnchor(item: view, attribute: .vcenter)
return LayoutAssemblyVAnchor(item: view.asView, attribute: .vcenter)
}
}

Expand All @@ -88,25 +88,25 @@ public enum VerticalAnchor {
case .topGuide: return nil
case .bottomGuide: return nil
case .centerGuide: return nil
case let .top(view): return view
case let .bottom(view): return view
case let .baseline(view): return view
case let .center(view): return view
case let .top(view): return view.asView
case let .bottom(view): return view.asView
case let .baseline(view): return view.asView
case let .center(view): return view.asView
}
}
}

public enum SizeAnchor {
case width(NativeView)
case height(NativeView)
case width(NativeViewable)
case height(NativeViewable)
case constant(Float)

fileprivate func lower() -> LayoutAssemblyDimensionAnchor? {
switch self {
case let .width(view):
return LayoutAssemblyDimensionAnchor(item: view, attribute: .width)
return LayoutAssemblyDimensionAnchor(item: view.asView, attribute: .width)
case let .height(view):
return LayoutAssemblyDimensionAnchor(item: view, attribute: .height)
return LayoutAssemblyDimensionAnchor(item: view.asView, attribute: .height)
case .constant(_): return nil
}
}
Expand Down Expand Up @@ -142,7 +142,7 @@ public enum ColumnLayout {
case topGuide
case space(Float)
case spaceOfAtLeast(Float)
case view(leading: Float? = nil, NativeView, trailing: Float? = nil)
case view(leading: Float? = nil, NativeViewable, trailing: Float? = nil)
case bottomGuide

func anchor(for side: VerticalSide) -> VerticalAnchor? {
Expand Down Expand Up @@ -196,7 +196,7 @@ public enum RowLayout {
case leadingGuide
case space(Float)
case spaceOfAtLeast(Float)
case view(NativeView)
case view(NativeViewable)
case trailingGuide

func anchor(for side: HorizontalSide) -> HorizontalAnchor? {
Expand Down Expand Up @@ -252,26 +252,26 @@ public enum Layout {
case valign(VerticalAnchor, Float, VerticalAnchor)
case size(SizeAnchor, SizeAnchor)

case leading(Float, NativeView)
case trailing(NativeView, Float)
case hmargin(Float, NativeView, Float)
case hmarginAtLeast(Float, NativeView, Float)
case hmarginTrailingAtLeast(Float, NativeView, Float)
case width(NativeView, SizeAnchor)
case maximumWidth(NativeView, SizeAnchor)
case hcenter(NativeView)
case hcenterContainer(NativeView, minMargin: Float, maxWidth: Float)
case leading(Float, NativeViewable)
case trailing(NativeViewable, Float)
case hmargin(Float, NativeViewable, Float)
case hmarginAtLeast(Float, NativeViewable, Float)
case hmarginTrailingAtLeast(Float, NativeViewable, Float)
case width(NativeViewable, SizeAnchor)
case maximumWidth(NativeViewable, SizeAnchor)
case hcenter(NativeViewable)
case hcenterContainer(NativeViewable, minMargin: Float, maxWidth: Float)
case row([RowLayout])

case top(Float, NativeView)
case bottom(NativeView, Float)
case vmargin(Float, NativeView, Float)
case vmarginAtLeast(Float, NativeView, Float)
case height(NativeView, SizeAnchor)
case vcenter(NativeView)
case top(Float, NativeViewable)
case bottom(NativeViewable, Float)
case vmargin(Float, NativeViewable, Float)
case vmarginAtLeast(Float, NativeViewable, Float)
case height(NativeViewable, SizeAnchor)
case vcenter(NativeViewable)
case column([ColumnLayout])

case center(NativeView)
case center(NativeViewable)

func compile() -> [LayoutAssembly] {
return lower().flatMap { $0.compile() }
Expand Down
28 changes: 28 additions & 0 deletions Sources/ViewKit/Standard/StandardViewController+iOS.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Foundation
#if canImport(UIKit)
import UIKit

open class StandardViewController: UIViewController {
private let realView: StandardView

public init(realView: StandardView) {
self.realView = realView
super.init(nibName: nil, bundle: nil)
}

@available(*, unavailable)
public required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

public override func loadView() {
view = realView
}

public override func viewDidLoad() {
super.viewDidLoad()
realView.hierarchy.install(on: self)
}
}

#endif
28 changes: 28 additions & 0 deletions Sources/ViewKit/Standard/StandardViewController+macOS.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Foundation
#if canImport(AppKit)
import AppKit

open class StandardViewController: NSViewController {
private let realView: StandardView

public init(realView: StandardView) {
self.realView = realView
super.init(nibName: nil, bundle: nil)
}

@available(*, unavailable)
public required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

public override func loadView() {
view = realView
}

public override func viewDidLoad() {
super.viewDidLoad()
realView.hierarchy.install(on: self)
}
}

#endif
13 changes: 13 additions & 0 deletions Sources/ViewKit/View/NativeViewable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Foundation

public protocol NativeViewable {
var asView: NativeView { get }
}

extension NativeView: NativeViewable {
public var asView: NativeView { self }
}

extension NativeViewController: NativeViewable {
public var asView: NativeView { view }
}
32 changes: 32 additions & 0 deletions Sources/ViewKit/View/ViewHierarchy.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ public enum ViewHierarchy {
case superview(NativeView, subviews: [NativeView])
case hierarchy(NativeView, subviews: [ViewHierarchy])
case views([NativeView])
case controller(NativeViewController)
case controllers([NativeViewController])

public func install(on view: NativeView) {
switch self {
Expand All @@ -27,6 +29,36 @@ public enum ViewHierarchy {
for subview in subviews {
view.install(view: subview)
}
case let .controller(controller):
view.install(view: controller.view)
case let .controllers(controllers):
for controller in controllers {
view.install(view: controller.view)
}
}
}

public func install(on controller: NativeViewController) {
for viewController in viewControllers {
controller.addChild(viewController)
}
}
}

private extension ViewHierarchy {
var viewControllers: [NativeViewController] {
var controllers = [NativeViewController]()
switch self {
case let .controller(controller):
controllers.append(controller)
case let .controllers(subcontrollers):
controllers.append(contentsOf: subcontrollers)
case .hierarchy(_, subviews: let hierarchy):
let subcontrollers = hierarchy.reduce([]) { $0 + $1.viewControllers }
controllers.append(contentsOf: subcontrollers)
case .superview, .views:
break // can't contain controllers
}
return controllers
}
}

0 comments on commit fa7a3e1

Please sign in to comment.