Skip to content

Commit

Permalink
Improve Badge and add before and after alignment
Browse files Browse the repository at this point in the history
  • Loading branch information
lkzhao committed Nov 11, 2021
1 parent 6e9cf72 commit 98c1c24
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 23 deletions.
48 changes: 31 additions & 17 deletions Sources/UIComponent/Components/Layout/Other/Badge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,25 @@ import BaseToolbox
///
/// Instead of using it directly, you can easily create a` Badge` component by using the `.badge` modifier.
/// ```swift
/// someComponent.badge(someOtherComponent, offset: CGVector(dx: 8, dy: -8))
/// someComponent.badge(someOtherComponent, offset: CGPoint(x: 8, y: -8))
/// ```
/// or
/// ```swift
/// someComponent.badge(offset: CGVector(dx: 8, dy: -8)) {
/// someComponent.badge(offset: CGPoint(x: 8, y: -8)) {
/// someOtherComponent
/// }
/// ```
///
/// Checkout the `ComplexLayoutViewController.swift` for other examples.
public struct Badge: Component {
public enum Alignment: CaseIterable {
case start, end, center, stretch, before, after
}
let child: Component
let overlay: Component
let verticalAlignment: CrossAxisAlignment
let horizontalAlignment: CrossAxisAlignment
let offset: CGVector
let verticalAlignment: Alignment
let horizontalAlignment: Alignment
let offset: CGPoint

public func layout(_ constraint: Constraint) -> RenderNode {
let childRenderNode = child.layout(constraint)
Expand All @@ -38,32 +41,43 @@ public struct Badge: Component {
width: horizontalAlignment == .stretch ? childRenderNode.size.width : -.infinity,
height: verticalAlignment == .stretch ? childRenderNode.size.height : -.infinity
),
maxSize: childRenderNode.size
maxSize: CGSize(
width: horizontalAlignment == .stretch ? childRenderNode.size.width : .infinity,
height: verticalAlignment == .stretch ? childRenderNode.size.height : .infinity
)
)
)
let beagePosition: (x: CGFloat, y: CGFloat)
let badgePosition: (x: CGFloat, y: CGFloat)
switch horizontalAlignment {
case .start:
beagePosition.x = 0
badgePosition.x = 0
case .end:
beagePosition.x = (childRenderNode.size.width - badgeRenderNode.size.width)
badgePosition.x = (childRenderNode.size.width - badgeRenderNode.size.width)
case .center:
beagePosition.x = (childRenderNode.size.width / 2 - badgeRenderNode.size.width / 2)
badgePosition.x = (childRenderNode.size.width / 2 - badgeRenderNode.size.width / 2)
case .stretch:
beagePosition.x = 0
badgePosition.x = 0
case .before:
badgePosition.x = -badgeRenderNode.size.width
case .after:
badgePosition.x = childRenderNode.size.width
}
switch verticalAlignment {
case .start:
beagePosition.y = 0
badgePosition.y = 0
case .end:
beagePosition.y = (childRenderNode.size.height - badgeRenderNode.size.height)
badgePosition.y = (childRenderNode.size.height - badgeRenderNode.size.height)
case .center:
beagePosition.y = (childRenderNode.size.height / 2 - badgeRenderNode.size.height / 2)
badgePosition.y = (childRenderNode.size.height / 2 - badgeRenderNode.size.height / 2)
case .stretch:
beagePosition.y = 0
badgePosition.y = 0
case .before:
badgePosition.y = -badgeRenderNode.size.height
case .after:
badgePosition.y = childRenderNode.size.height
}
let finallyBadgePosition = CGPoint(x: beagePosition.x + offset.dx, y: beagePosition.y + offset.dy)
let finallyBadgePosition = CGPoint(x: badgePosition.x + offset.x, y: badgePosition.y + offset.y)

return SlowRenderNode(size: childRenderNode.size, children: [childRenderNode, badgeRenderNode], positions: [.zero, finallyBadgePosition])
return AlwaysRenderNode(size: childRenderNode.size, children: [childRenderNode, badgeRenderNode], positions: [.zero, finallyBadgePosition])
}
}
35 changes: 35 additions & 0 deletions Sources/UIComponent/Components/Layout/Stack/StackRenderNode.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Created by Luke Zhao on 8/22/20.

import UIKit
import BaseToolbox

public protocol StackRenderNode: RenderNode, BaseLayoutProtocol {
var size: CGSize { get }
Expand Down Expand Up @@ -73,3 +74,37 @@ public struct SlowRenderNode: RenderNode {
return IndexSet(result)
}
}

public struct AlwaysRenderNode: RenderNode {
public let size: CGSize
public let children: [RenderNode]
public let positions: [CGPoint]

public init(size: CGSize, children: [RenderNode], positions: [CGPoint]) {
self.size = size
self.children = children
self.positions = positions
}

public func visibleRenderables(in frame: CGRect) -> [Renderable] {
var result = [Renderable]()
for i in 0..<children.count {
let child = children[i]
let position = positions[i]
let childFrame = CGRect(origin: .zero, size: child.size)
let childRenderables = child.visibleRenderables(in: childFrame)
.map {
Renderable(
id: $0.id,
keyPath: "\(type(of: self))-\(i)." + $0.keyPath,
animator: $0.animator,
renderNode: $0.renderNode,
frame: CGRect(origin: $0.frame.origin + position, size: $0.frame.size)
)
}
result.append(contentsOf: childRenderables)
}
return result
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ extension Component {
extension Component {
public func badge(
_ component: Component,
verticalAlignment: CrossAxisAlignment = .start,
horizontalAlignment: CrossAxisAlignment = .end,
offset: CGVector = .zero
verticalAlignment: Badge.Alignment = .start,
horizontalAlignment: Badge.Alignment = .end,
offset: CGPoint = .zero
) -> Badge {
Badge(
child: self,
Expand All @@ -52,9 +52,9 @@ extension Component {
)
}
public func badge(
verticalAlignment: CrossAxisAlignment = .start,
horizontalAlignment: CrossAxisAlignment = .end,
offset: CGVector = .zero,
verticalAlignment: Badge.Alignment = .start,
horizontalAlignment: Badge.Alignment = .end,
offset: CGPoint = .zero,
_ component: () -> Component
) -> Badge {
Badge(
Expand Down

0 comments on commit 98c1c24

Please sign in to comment.