From 7b3ecfffc59d2d980d9f7628365b64c20fe015be Mon Sep 17 00:00:00 2001 From: Runt <qingingrunt2010@qq.com> Date: Sun, 27 Jul 2025 09:42:03 +0000 Subject: [PATCH] 多个小窗缩放问题修复 --- LiveProject/views/FlowLayout.swift | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 119 insertions(+), 0 deletions(-) diff --git a/LiveProject/views/FlowLayout.swift b/LiveProject/views/FlowLayout.swift index f3ee86a..038d158 100644 --- a/LiveProject/views/FlowLayout.swift +++ b/LiveProject/views/FlowLayout.swift @@ -4,4 +4,123 @@ // // Created by 倪路朋 on 6/26/25. // +import SwiftUI +struct FlowLayout: Layout { + var spacing: CGFloat = 8 + var lineSpacing: CGFloat = 8 + + func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize { + var width: CGFloat = 0 + var height: CGFloat = 0 + var currentLineWidth: CGFloat = 0 + var currentLineHeight: CGFloat = 0 + let maxWidth = proposal.width ?? .infinity + + for view in subviews { + let size = view.sizeThatFits(.unspecified) + if currentLineWidth + size.width > maxWidth { + width = max(width, currentLineWidth) + height += currentLineHeight + lineSpacing + currentLineWidth = size.width + currentLineHeight = size.height + } else { + currentLineWidth += size.width + spacing + currentLineHeight = max(currentLineHeight, size.height) + } + } + + width = max(width, currentLineWidth) + height += currentLineHeight + + return CGSize(width: width, height: height) + } + + func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) { + var x: CGFloat = 0 + var y: CGFloat = 0 + var lineHeight: CGFloat = 0 + + for view in subviews { + let size = view.sizeThatFits(.unspecified) + + if x + size.width > bounds.width { + x = 0 + y += lineHeight + lineSpacing + lineHeight = 0 + } + + view.place( + at: CGPoint(x: bounds.minX + x, y: bounds.minY + y), + proposal: ProposedViewSize(width: size.width, height: size.height) + ) + + x += size.width + spacing + lineHeight = max(lineHeight, size.height) + } + } +} +// MARK: - 使用示例 + +struct FlowLayoutExample: View { + let tags = [ + "Swift" + ] + + @State private var newTag = "" + @State private var customTags = ["自定义标签1", "自定义标签2"] + + var body: some View { + VStack{ + VStack(spacing: 20) { + FlowLayout(){ + + ForEach(tags, id: \.self) { item in + Text(item) + .padding(.horizontal, 12) + .padding(.vertical, 6) + .background(Color.blue.opacity(0.2)) + .cornerRadius(8) + } + }.frame(alignment:.leading) + .background(Color.red) + } + .frame(maxWidth: .infinity,alignment:.leading) + } + .background(Color.black) + } + + private func addTag() { + withAnimation { + customTags.append(newTag) + newTag = "" + } + } +} + +/// 标签视图 +struct TagView: View { + let text: String + + var body: some View { + Text(text) + .padding(.horizontal, 12) + .padding(.vertical, 8) + .background(Color.blue.opacity(0.2)) + .foregroundColor(.blue) + .cornerRadius(10) + .overlay( + RoundedRectangle(cornerRadius: 10) + .stroke(Color.blue, lineWidth: 1) + ) + .fixedSize(horizontal: true, vertical: false) // 确保文本不被截断 + } +} + +// MARK: - 预览 + +struct FlowLayout_Previews: PreviewProvider { + static var previews: some View { + FlowLayoutExample() + } +} -- Gitblit v1.9.1