First version

This commit is contained in:
Christoph Hagen
2024-10-14 19:22:32 +02:00
parent 7c812de089
commit 0989f06d87
51 changed files with 2477 additions and 234 deletions

View 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
}
}
}

View 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")
}
}