You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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)
}

关键说明

  1. 自适应网格项:GridItem(.adaptive(minimum: 80))指定每个单词的最小宽度为80pt,系统会自动根据当前容器宽度,计算每行能容纳的最大单词数量,自动换行。
  2. 简化遍历逻辑:通过enumerated()直接获取单词的索引和内容,无需手动计算行列索引,代码更简洁可靠。
  3. 保留最少行数(可选):如果需要维持原代码中最少显示2行的需求,通过计算补充空白占位视图,确保布局高度符合预期。

内容的提问来源于stack exchange,提问作者Iku

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 20:39:51