Skip to content

Commit

Permalink
Add SwiftUI-style builder functions to reduce nesting.
Browse files Browse the repository at this point in the history
  • Loading branch information
kyleve committed Apr 30, 2020
1 parent d819059 commit 827f9bc
Show file tree
Hide file tree
Showing 14 changed files with 207 additions and 76 deletions.
15 changes: 15 additions & 0 deletions BlueprintUI/Sources/Layout/Aligned.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,18 @@ public struct Aligned: Element {
}
}
}

public extension Element {
/// Wraps the element in an `Aligned` element with the provided parameters.
///
/// - parameters:
/// - vertically: The vertical alignment. Defaults to centered.
/// - horizontally: The horizontal alignment. Defaults to centered.
func aligned(vertically: Aligned.VerticalAlignment = .center, horizontally: Aligned.HorizontalAlignment = .center) -> Aligned {
Aligned(
vertically: vertically,
horizontally: horizontally,
wrapping: self
)
}
}
9 changes: 9 additions & 0 deletions BlueprintUI/Sources/Layout/Centered.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,12 @@ public struct Centered: ProxyElement {
return Aligned(vertically: .center, horizontally: .center, wrapping: wrappedElement)
}
}


public extension Element {

/// Wraps the element in a `Centered` element to center it within its parent.
func centered() -> Centered {
Centered(self)
}
}
14 changes: 14 additions & 0 deletions BlueprintUI/Sources/Layout/ConstrainedAspectRatio.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,17 @@ public struct ConstrainedAspectRatio: Element {
}
}
}


public extension ConstrainedAspectRatio {
/// Initializes with the given properties.
///
/// - parameters:
/// - aspectRatio: The aspect ratio that the content size should match.
/// - contentMode: Whether the aspect ratio should be reached by expanding the content
/// element's size to fill its parent or shrinking it to fit.
/// - wrapping: The content element.
func aspectRatio(with aspectRatio: AspectRatio, contentMode: ContentMode = .fill) -> ConstrainedAspectRatio {
ConstrainedAspectRatio(aspectRatio: aspectRatio, contentMode: contentMode, wrapping: self)
}
}
13 changes: 11 additions & 2 deletions BlueprintUI/Sources/Layout/ConstrainedSize.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@ extension ConstrainedSize {

}

public extension Element {

func constrainedTo(
width: ConstrainedSize.Constraint = .unconstrained,
height: ConstrainedSize.Constraint = .unconstrained
) -> ConstrainedSize
{
ConstrainedSize(width: width, height: height, wrapping: self)
}
}

extension Comparable {

fileprivate func clamped(to limits: ClosedRange<Self>) -> Self {
Expand Down Expand Up @@ -80,5 +91,3 @@ extension ConstrainedSize {
}

}


31 changes: 26 additions & 5 deletions BlueprintUI/Sources/Layout/Inset.swift
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,16 @@ public struct Inset: Element {
left: sideInsets,
bottom: 0.0,
right: sideInsets),
wrapping: element)
wrapping: element
)
}

public init(vertical: CGFloat, wrapping element: Element) {
self.init(
top: vertical,
bottom: vertical,
wrapping: element)
wrapping: element
)
}

public var content: ElementContent {
Expand All @@ -63,13 +65,34 @@ public struct Inset: Element {
top: top,
bottom: bottom,
left: left,
right: right))
right: right
)
)
}

public func backingViewDescription(bounds: CGRect, subtreeExtent: CGRect?) -> ViewDescription? {
return nil
}
}


public extension Element {

func inset(top: CGFloat = 0.0, bottom: CGFloat = 0.0, left: CGFloat = 0.0, right: CGFloat = 0.0) -> Inset {
Inset(top: top, bottom: bottom, left: left, right: right, wrapping: self)
}

func inset(by edgeInsets : UIEdgeInsets) -> Inset {
Inset(insets: edgeInsets, wrapping: self)
}

func inset(uniform : CGFloat) -> Inset {
Inset(uniformInset: uniform, wrapping: self)
}

func inset(horizontal : CGFloat = 0.0, vertical : CGFloat = 0.0) -> Inset {
Inset(top: vertical, bottom: vertical, left: horizontal, right: horizontal, wrapping: self)
}
}


Expand Down Expand Up @@ -103,7 +126,5 @@ extension Inset {
frame.size.height -= top + bottom
return LayoutAttributes(frame: frame)
}

}

}
14 changes: 14 additions & 0 deletions BlueprintUI/Sources/Layout/Spacer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,20 @@ public struct Spacer: Element {
public init(size: CGSize) {
self.size = size
}

/// Initializes a new spacer with the given width and height.
public init(width : CGFloat = 0.0, height : CGFloat = 0.0) {
self.init(
size: CGSize(width: width, height: height)
)
}

/// Initializes a new spacer with the given value for the width and height.
public init(_ value : CGFloat) {
self.init(
size: CGSize(width: value, height: value)
)
}

public var content: ElementContent {
return ElementContent(intrinsicSize: size)
Expand Down
5 changes: 5 additions & 0 deletions BlueprintUICommonControls/Sources/AccessibilityBlocker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,10 @@ public struct AccessibilityBlocker: Element {
config[\.accessibilityElementsHidden] = true
}
}
}

public extension Element {
func disableAccessibility() -> AccessibilityBlocker {
AccessibilityBlocker(wrapping: self)
}
}
24 changes: 22 additions & 2 deletions BlueprintUICommonControls/Sources/AccessibilityElement.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ public struct AccessibilityElement: Element {
hint: String? = nil,
identifier: String? = nil,
traits: Set<Trait> = [],
wrapping element: Element)
{
wrapping element: Element
) {
self.label = label
self.value = value
self.hint = hint
Expand Down Expand Up @@ -105,5 +105,25 @@ public struct AccessibilityElement: Element {
config[\.isAccessibilityElement] = true
}
}
}


public extension AccessibilityElement {
func accessibility(
label: String? = nil,
value: String? = nil,
hint: String? = nil,
identifier: String? = nil,
traits: Set<Trait> = []
) -> AccessibilityElement
{
AccessibilityElement(
label: label,
value: value,
hint: hint,
identifier: identifier,
traits: traits,
wrapping: self
)
}
}
42 changes: 36 additions & 6 deletions BlueprintUICommonControls/Sources/Box.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,28 @@ import BlueprintUI
/// background color.
public struct Box: Element {

public var backgroundColor: UIColor = .clear
public var cornerStyle: CornerStyle = .square
public var borderStyle: BorderStyle = .none
public var shadowStyle: ShadowStyle = .none
public var clipsContent: Bool = false
public var backgroundColor: UIColor
public var cornerStyle: CornerStyle
public var borderStyle: BorderStyle
public var shadowStyle: ShadowStyle
public var clipsContent: Bool

public var wrappedElement: Element?

public init(backgroundColor: UIColor = .clear, cornerStyle: CornerStyle = .square, wrapping element: Element? = nil) {
public init(
backgroundColor: UIColor = .clear,
cornerStyle: CornerStyle = .square,
borderStyle: BorderStyle = .none,
shadowStyle: ShadowStyle = .none,
clipsContent: Bool = false,
wrapping element: Element? = nil
) {
self.backgroundColor = backgroundColor
self.cornerStyle = cornerStyle
self.borderStyle = borderStyle
self.shadowStyle = shadowStyle
self.clipsContent = clipsContent

self.wrappedElement = element
}

Expand Down Expand Up @@ -103,7 +114,26 @@ extension Box {
case none
case simple(radius: CGFloat, opacity: CGFloat, offset: CGSize, color: UIColor)
}
}

public extension Element {
func box(
background: UIColor = .clear,
corners: Box.CornerStyle = .square,
borders: Box.BorderStyle = .none,
shadow: Box.ShadowStyle = .none,
clipsContent: Bool = false
) -> Box
{
Box(
backgroundColor: background,
cornerStyle: corners,
borderStyle: borders,
shadowStyle: shadow,
clipsContent: clipsContent,
wrapping: self
)
}
}

extension Box.CornerStyle {
Expand Down
25 changes: 23 additions & 2 deletions BlueprintUICommonControls/Sources/ScrollView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ public struct ScrollView: Element {
public var wrappedElement: Element

/// Determines the sizing behavior of the content within the scroll view.
public var contentSize: ContentSize = .fittingHeight
public var contentSize: ContentSize
public var alwaysBounceVertical = false
public var alwaysBounceHorizontal = false

Expand All @@ -30,8 +30,15 @@ public struct ScrollView: Element {
public var keyboardAdjustmentMode : KeyboardAdjustmentMode = .adjustsWhenVisible


public init(wrapping element: Element) {
public init(
_ contentSize: ContentSize = .fittingHeight,
wrapping element: Element,
configure : (inout ScrollView) -> () = { _ in }
) {
self.contentSize = contentSize
self.wrappedElement = element

configure(&self)
}

public var content: ElementContent {
Expand Down Expand Up @@ -61,6 +68,20 @@ public struct ScrollView: Element {
}
}

public extension Element {
func scrollable(
_ contentSize: ScrollView.ContentSize = .fittingHeight,
configure : (inout ScrollView) -> () = { _ in }
) -> ScrollView
{
ScrollView(
contentSize,
wrapping: self,
configure: configure
)
}
}

extension ScrollView {

fileprivate struct Layout: SingleChildLayout {
Expand Down
3 changes: 2 additions & 1 deletion BlueprintUICommonControls/Sources/TextField.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ public struct TextField: Element {
public var becomeActiveTrigger: Trigger?
public var resignActiveTrigger: Trigger?

public init(text: String) {
public init(text: String, configure : (inout TextField) -> () = { _ in }) {
self.text = text
configure(&self)
}

public func backingViewDescription(bounds: CGRect, subtreeExtent: CGRect?) -> ViewDescription? {
Expand Down
23 changes: 7 additions & 16 deletions SampleApp/Sources/ScrollViewKeyboardViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,17 @@ final class ScrollViewKeyboardViewController : UIViewController

private func content() -> Element
{
var scrollView = ScrollView(wrapping: Column {
Column {
$0.horizontalAlignment = .fill

for _ in 1...20 {
let textField = TextField(text: "Hello")

let box = Box(
backgroundColor: .init(white: 0.95, alpha: 1.0),
cornerStyle: .square,
wrapping: Inset(uniformInset: 20.0, wrapping: textField)
$0.add(growPriority: 0.0, shrinkPriority: 0.0, child: TextField(text: "Hello, World")
.inset(uniform: 20.0)
.box(background: .init(white: 0.95, alpha: 1.0))
)

$0.add(child: box)
}
})

//scrollView.contentInset.bottom = 20.0

scrollView.keyboardAdjustmentMode = .adjustsWhenVisible

return scrollView
}.scrollable {
$0.keyboardAdjustmentMode = .adjustsWhenVisible
}
}
}
Loading

0 comments on commit 827f9bc

Please sign in to comment.