37 lines
1.3 KiB
Swift
Executable File
37 lines
1.3 KiB
Swift
Executable File
import SwiftUI
|
|
|
|
struct FlowLayout: Layout {
|
|
var spacing: CGFloat = 8
|
|
|
|
func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize {
|
|
let width = proposal.width ?? .infinity
|
|
var x: CGFloat = 0, y: CGFloat = 0, rowHeight: CGFloat = 0
|
|
for view in subviews {
|
|
let size = view.sizeThatFits(.unspecified)
|
|
if x + size.width > width, x > 0 {
|
|
x = 0
|
|
y += rowHeight + spacing
|
|
rowHeight = 0
|
|
}
|
|
x += size.width + spacing
|
|
rowHeight = max(rowHeight, size.height)
|
|
}
|
|
return CGSize(width: width.isFinite ? width : x, height: y + rowHeight)
|
|
}
|
|
|
|
func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) {
|
|
var x = bounds.minX, y = bounds.minY, rowHeight: CGFloat = 0
|
|
for view in subviews {
|
|
let size = view.sizeThatFits(.unspecified)
|
|
if x + size.width > bounds.maxX, x > bounds.minX {
|
|
x = bounds.minX
|
|
y += rowHeight + spacing
|
|
rowHeight = 0
|
|
}
|
|
view.place(at: CGPoint(x: x, y: y), proposal: ProposedViewSize(size))
|
|
x += size.width + spacing
|
|
rowHeight = max(rowHeight, size.height)
|
|
}
|
|
}
|
|
}
|