Created
July 9, 2023 21:37
-
-
Save aheze/1cbd2d36764c978b28aa20a00cb4b5b6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct OverflowLayout: Layout { | |
var spacing = CGFloat(10) | |
func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize { | |
let containerWidth = proposal.replacingUnspecifiedDimensions().width | |
let sizes = subviews.map { $0.sizeThatFits(.unspecified) } | |
return layout(sizes: sizes, containerWidth: containerWidth).size | |
} | |
func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) { | |
let sizes = subviews.map { $0.sizeThatFits(.unspecified) } | |
let offsets = layout(sizes: sizes, containerWidth: bounds.width).offsets | |
for (offset, subview) in zip(offsets, subviews) { | |
subview.place(at: CGPoint(x: offset.x + bounds.minX, y: offset.y + bounds.minY), proposal: .unspecified) | |
} | |
} | |
func layout(sizes: [CGSize], containerWidth: CGFloat) -> (offsets: [CGPoint], size: CGSize) { | |
var result: [CGPoint] = [] | |
var currentPosition: CGPoint = .zero | |
var lineHeight: CGFloat = 0 | |
var maxX: CGFloat = 0 | |
for size in sizes { | |
if currentPosition.x + size.width > containerWidth { | |
currentPosition.x = 0 | |
currentPosition.y += lineHeight + spacing | |
lineHeight = 0 | |
} | |
result.append(currentPosition) | |
currentPosition.x += size.width | |
maxX = max(maxX, currentPosition.x) | |
currentPosition.x += spacing | |
lineHeight = max(lineHeight, size.height) | |
} | |
return (result, CGSize(width: maxX, height: currentPosition.y + lineHeight)) | |
} | |
} | |
/// Usage | |
OverflowLayout(spacing: 10) { | |
ForEach(badges) { badge in | |
Text("Hello!") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment