First version
This commit is contained in:
53
CHDataManagement/Views/Generic/FlowHStack.swift
Normal file
53
CHDataManagement/Views/Generic/FlowHStack.swift
Normal file
@ -0,0 +1,53 @@
|
||||
import SwiftUI
|
||||
|
||||
struct FlowHStack: Layout {
|
||||
|
||||
var horizontalSpacing: CGFloat = 8
|
||||
|
||||
var verticalSpacing: CGFloat = 8
|
||||
|
||||
func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize {
|
||||
let subviewSizes = subviews.map { $0.sizeThatFits(proposal) }
|
||||
let maxSubviewHeight = subviewSizes.map { $0.height }.max() ?? .zero
|
||||
var currentRowWidth: CGFloat = .zero
|
||||
var totalHeight: CGFloat = maxSubviewHeight
|
||||
var totalWidth: CGFloat = .zero
|
||||
|
||||
for size in subviewSizes {
|
||||
let requestedRowWidth = currentRowWidth + horizontalSpacing + size.width
|
||||
let availableRowWidth = proposal.width ?? .zero
|
||||
let willOverflow = requestedRowWidth > availableRowWidth
|
||||
|
||||
if willOverflow {
|
||||
totalHeight += verticalSpacing + maxSubviewHeight
|
||||
currentRowWidth = size.width
|
||||
} else {
|
||||
currentRowWidth = requestedRowWidth
|
||||
}
|
||||
|
||||
totalWidth = max(totalWidth, currentRowWidth)
|
||||
}
|
||||
|
||||
return CGSize(width: totalWidth, height: totalHeight)
|
||||
}
|
||||
|
||||
func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) {
|
||||
let subviewSizes = subviews.map { $0.sizeThatFits(proposal) }
|
||||
let maxSubviewHeight = subviewSizes.map { $0.height }.max() ?? .zero
|
||||
var point = CGPoint(x: bounds.minX, y: bounds.minY)
|
||||
|
||||
for index in subviews.indices {
|
||||
let requestedWidth = point.x + subviewSizes[index].width
|
||||
let availableWidth = bounds.maxX
|
||||
let willOverflow = requestedWidth > availableWidth
|
||||
|
||||
if willOverflow {
|
||||
point.x = bounds.minX
|
||||
point.y += maxSubviewHeight + verticalSpacing
|
||||
}
|
||||
|
||||
subviews[index].place(at: point, proposal: ProposedViewSize(subviewSizes[index]))
|
||||
point.x += subviewSizes[index].width + horizontalSpacing
|
||||
}
|
||||
}
|
||||
}
|
33
CHDataManagement/Views/Generic/HorizontalCenter.swift
Normal file
33
CHDataManagement/Views/Generic/HorizontalCenter.swift
Normal file
@ -0,0 +1,33 @@
|
||||
import SwiftUI
|
||||
|
||||
/**
|
||||
A view that centers the content horizontally using an `HStack`
|
||||
*/
|
||||
struct HorizontalCenter<Content> : View where Content : View {
|
||||
|
||||
let alignment: VerticalAlignment
|
||||
|
||||
let spacing: CGFloat?
|
||||
|
||||
let content: Content
|
||||
|
||||
public init(alignment: VerticalAlignment = .center, spacing: CGFloat? = nil, @ViewBuilder content: () -> Content) {
|
||||
self.alignment = alignment
|
||||
self.spacing = spacing
|
||||
self.content = content()
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
HStack(alignment: alignment, spacing: spacing) {
|
||||
Spacer()
|
||||
content
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Preview {
|
||||
HorizontalCenter {
|
||||
Text("Test")
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user