Skip to content

Commit

Permalink
fix a stack layout issue with minSize and API cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
lkzhao committed May 29, 2022
1 parent 6bce4e3 commit 6707fa1
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 30 deletions.
12 changes: 6 additions & 6 deletions Sources/UIComponent/Components/Layout/Inset/Insets.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@ import BaseToolbox
import UIKit

public struct Insets: Component {
let insets: UIEdgeInsets
let child: Component
public init(insets: UIEdgeInsets, child: Component) {
self.insets = insets
let insets: UIEdgeInsets
public init(child: Component, insets: UIEdgeInsets) {
self.child = child
self.insets = insets
}
public func layout(_ constraint: Constraint) -> RenderNode {
InsetsRenderNode(child: child.layout(constraint.inset(by: insets)), insets: insets)
}
}

public struct DynamicInsets: Component {
let insetProvider: (Constraint) -> UIEdgeInsets
let child: Component
public init(insetProvider: @escaping (Constraint) -> UIEdgeInsets, child: Component) {
self.insetProvider = insetProvider
let insetProvider: (Constraint) -> UIEdgeInsets
public init(child: Component, insetProvider: @escaping (Constraint) -> UIEdgeInsets) {
self.child = child
self.insetProvider = insetProvider
}
public func layout(_ constraint: Constraint) -> RenderNode {
let insets = insetProvider(constraint)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,36 @@
import UIKit

public struct VisibleFrameInsets: Component {
let insets: UIEdgeInsets
let child: Component
let insets: UIEdgeInsets

public init(insets: UIEdgeInsets, child: Component) {
self.insets = insets
public init(child: Component, insets: UIEdgeInsets) {
self.child = child
self.insets = insets
}

public func layout(_ constraint: Constraint) -> RenderNode {
VisibleFrameInsetRenderNode(insets: insets, child: child.layout(constraint))
VisibleFrameInsetRenderNode(child: child.layout(constraint), insets: insets)
}
}

public struct DynamicVisibleFrameInset: Component {
let insetProvider: (CGRect) -> UIEdgeInsets
let child: Component
let insetProvider: (CGRect) -> UIEdgeInsets

public init(insetProvider: @escaping (CGRect) -> UIEdgeInsets, child: Component) {
self.insetProvider = insetProvider
public init(child: Component, insetProvider: @escaping (CGRect) -> UIEdgeInsets) {
self.child = child
self.insetProvider = insetProvider
}

public func layout(_ constraint: Constraint) -> RenderNode {
DynamicVisibleFrameInsetRenderNode(insetProvider: insetProvider, child: child.layout(constraint))
DynamicVisibleFrameInsetRenderNode(child: child.layout(constraint), insetProvider: insetProvider)
}
}

struct VisibleFrameInsetRenderNode: RenderNode {
let insets: UIEdgeInsets
let child: RenderNode
let insets: UIEdgeInsets
var size: CGSize {
child.size
}
Expand All @@ -48,8 +48,8 @@ struct VisibleFrameInsetRenderNode: RenderNode {
}

struct DynamicVisibleFrameInsetRenderNode: RenderNode {
let insetProvider: (CGRect) -> UIEdgeInsets
let child: RenderNode
let insetProvider: (CGRect) -> UIEdgeInsets
var size: CGSize {
child.size
}
Expand Down
5 changes: 3 additions & 2 deletions Sources/UIComponent/Components/Layout/Stack/Stack.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ extension Stack {

let maxPrimary = main(constraint.maxSize)
let minPrimary = main(constraint.minSize)
let primaryBound = minPrimary > 0 ? minPrimary : maxPrimary
let (offset, distributedSpacing) = LayoutHelper.distribute(
justifyContent: justifyContent,
maxPrimary: maxPrimary == .infinity && minPrimary > 0 ? minPrimary : maxPrimary,
maxPrimary: primaryBound,
totalPrimary: mainTotal,
minimunSpacing: spacing,
numberOfItems: renderNodes.count
Expand All @@ -57,7 +58,7 @@ extension Stack {
primaryOffset += main(child.size) + distributedSpacing
}
let intrisicMain = primaryOffset - distributedSpacing
let finalMain = justifyContent != .start && main(constraint.maxSize) != .infinity ? max(main(constraint.maxSize), intrisicMain) : intrisicMain
let finalMain = justifyContent != .start && primaryBound != .infinity ? max(primaryBound, intrisicMain) : intrisicMain
let finalSize = size(main: finalMain, cross: crossMax)

return renderNode(size: finalSize, children: renderNodes, positions: positions)
Expand Down
57 changes: 45 additions & 12 deletions Sources/UIComponent/Core/Model/Component/Component+Modifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -78,34 +78,67 @@ extension Component {

extension Component {
public func inset(_ amount: CGFloat) -> Component {
Insets(insets: UIEdgeInsets(top: amount, left: amount, bottom: amount, right: amount), child: self)
Insets(child: self, insets: UIEdgeInsets(top: amount, left: amount, bottom: amount, right: amount))
}
public func inset(h: CGFloat = 0, v: CGFloat = 0) -> Component {
Insets(insets: UIEdgeInsets(top: v, left: h, bottom: v, right: h), child: self)
public func inset(h: CGFloat, v: CGFloat) -> Component {
Insets(child: self, insets: UIEdgeInsets(top: v, left: h, bottom: v, right: h))
}
public func inset(v: CGFloat, h: CGFloat) -> Component {
Insets(child: self, insets: UIEdgeInsets(top: v, left: h, bottom: v, right: h))
}
public func inset(h: CGFloat) -> Component {
Insets(child: self, insets: UIEdgeInsets(top: 0, left: h, bottom: 0, right: h))
}
public func inset(v: CGFloat) -> Component {
Insets(child: self, insets: UIEdgeInsets(top: v, left: 0, bottom: v, right: 0))
}
public func inset(top: CGFloat = 0, left: CGFloat = 0, bottom: CGFloat = 0, right: CGFloat = 0) -> Component {
Insets(insets: UIEdgeInsets(top: top, left: left, bottom: bottom, right: right), child: self)
Insets(child: self, insets: UIEdgeInsets(top: top, left: left, bottom: bottom, right: right))
}
public func inset(by insets: UIEdgeInsets) -> Component {
Insets(insets: insets, child: self)
public func inset(_ insets: UIEdgeInsets) -> Component {
Insets(child: self, insets: insets)
}
public func inset(_ insetProvider: @escaping (Constraint) -> UIEdgeInsets) -> Component {
DynamicInsets(insetProvider: insetProvider, child: self)
DynamicInsets(child: self, insetProvider: insetProvider)
}
}

extension Component {
public func offset(_ offset: CGPoint) -> Component {
Insets(child: self, insets: UIEdgeInsets(top: offset.y, left: offset.x, bottom: -offset.y, right: -offset.x))
}
public func offset(x: CGFloat = 0, y: CGFloat = 0) -> Component {
Insets(child: self, insets: UIEdgeInsets(top: y, left: x, bottom: -y, right: -x))
}
public func offset(_ offsetProvider: @escaping (Constraint) -> CGPoint) -> Component {
DynamicInsets(child: self) {
let offset = offsetProvider($0)
return UIEdgeInsets(top: offset.y, left: offset.x, bottom: -offset.y, right: -offset.x)
}
}
}

extension Component {
public func visibleInset(_ amount: CGFloat) -> Component {
VisibleFrameInsets(insets: UIEdgeInsets(top: amount, left: amount, bottom: amount, right: amount), child: self)
VisibleFrameInsets(child: self, insets: UIEdgeInsets(top: amount, left: amount, bottom: amount, right: amount))
}
public func visibleInset(h: CGFloat, v: CGFloat) -> Component {
VisibleFrameInsets(child: self, insets: UIEdgeInsets(top: v, left: h, bottom: v, right: h))
}
public func visibleInset(v: CGFloat, h: CGFloat) -> Component {
VisibleFrameInsets(child: self, insets: UIEdgeInsets(top: v, left: h, bottom: v, right: h))
}
public func visibleInset(h: CGFloat) -> Component {
VisibleFrameInsets(child: self, insets: UIEdgeInsets(top: 0, left: h, bottom: 0, right: h))
}
public func visibleInset(h: CGFloat = 0, v: CGFloat = 0) -> Component {
VisibleFrameInsets(insets: UIEdgeInsets(top: v, left: h, bottom: v, right: h), child: self)
public func visibleInset(v: CGFloat) -> Component {
VisibleFrameInsets(child: self, insets: UIEdgeInsets(top: v, left: 0, bottom: v, right: 0))
}
public func visibleInset(_ insets: UIEdgeInsets) -> Component {
VisibleFrameInsets(insets: insets, child: self)
VisibleFrameInsets(child: self, insets: insets)
}
public func visibleInset(_ insetProvider: @escaping (CGRect) -> UIEdgeInsets) -> Component {
DynamicVisibleFrameInset(insetProvider: insetProvider, child: self)
DynamicVisibleFrameInset(child: self, insetProvider: insetProvider)
}
}

Expand Down

0 comments on commit 6707fa1

Please sign in to comment.