如何在SwiftUI中让每行动态容纳尽可能多的单词?
SwiftUI 实现单词流式布局(动态每行容纳最多单词)
问题分析
你当前的代码通过固定每行4个单词的方式布局,导致短单词时行内出现多余空白。要实现每行动态容纳尽可能多的单词,需要利用SwiftUI的自适应布局能力,替换手动计算行列的逻辑。
修改方案
使用LazyVGrid配合自适应网格项,让系统自动根据容器宽度分配每行的单词数量,实现流式换行效果。以下是修改后的完整代码:
ScrollView { // 配置自适应网格:每个单词最小宽度80,自动计算每行数量 LazyVGrid(columns: [GridItem(.adaptive(minimum: 80), spacing: 5)], spacing: 10) { // 直接遍历单词数组,同时获取索引 ForEach(Array(viewModel.arrangedWords.enumerated()), id: \.offset) { index, targetWord in Text(targetWord) .foregroundColor(.white) .padding() .background(Rectangle().fill(Color.green.opacity(0.8))) .cornerRadius(10) .frame(height: 60) .onTapGesture { viewModel.moveWordOutOfSpace(index: index) print("arranged words: \(viewModel.arrangedWords)") } } // 可选:保留原逻辑中的最少2行显示需求 let screenWidth = UIScreen.main.bounds.width let maxItemsPerRow = Int(screenWidth / 80) // 每行最多能容纳的单词数 let minTotalItems = maxItemsPerRow * 2 let emptyItemsNeeded = max(0, minTotalItems - viewModel.arrangedWords.count) ForEach(0..<emptyItemsNeeded, id: \.self) { _ in Color.clear.frame(height: 60) } } .frame(maxWidth: .infinity, alignment: .leading) .background(Color.blue) .padding(10) }
关键说明
- 自适应网格项:
GridItem(.adaptive(minimum: 80))指定每个单词的最小宽度为80pt,系统会自动根据当前容器宽度,计算每行能容纳的最大单词数量,自动换行。 - 简化遍历逻辑:通过
enumerated()直接获取单词的索引和内容,无需手动计算行列索引,代码更简洁可靠。 - 保留最少行数(可选):如果需要维持原代码中最少显示2行的需求,通过计算补充空白占位视图,确保布局高度符合预期。
内容的提问来源于stack exchange,提问作者Iku
相关产品推荐
相关产品推荐

