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

LazyVGrid中按钮间出现异常间隙,如何解决?

LazyVGrid间隙问题的原因及解决方法

问题根源

你的代码生成dates数组时会产生重复的Date值:

  • 当计算出的时间为12:00/12:15/12:30/12:45时,代码会给这些时间加1小时,转为13:00/13:15/13:30/13:45。
  • 后续的interval计算会自然生成上述13点时段的时间,导致数组中出现重复的Date。
  • 由于ForEach使用id: \.self作为元素唯一标识,重复的Date会被视为同一元素,不会重复渲染,最终网格中出现空白间隙。

解决方法

方法一:避免生成重复Date(推荐)

修改dates数组的生成逻辑,直接跳过12点时段的时间,从根源上消除重复:

let dates: [Date] = (0...34).compactMap { interval -> Date? in
    var components = Calendar.current.dateComponents([.day, .month, .year], from: Date())
    components.hour = 7
    components.minute = 30
    
    guard var date = Calendar.current.date(from: components) else { return nil }
    
    date.addTimeInterval(Double(900 * interval))
    
    // 直接过滤12点的时间,不加入数组
    if Calendar.current.component(.hour, from: date) == 12 {
        return nil
    }
    
    return date
}

方法二:优化按钮布局(让按钮占满列宽)

如果希望按钮填满网格列的宽度,让整体布局更整齐,可以给Capsule添加宽高约束:

Button {
} label: {
    Capsule()
        .overlay {
            Text(text(for: date))
                .foregroundStyle(.white)
        }
        .foregroundColor(.blue)
        .frame(height: 44)
        .frame(maxWidth: .infinity) // 让胶囊按钮占满列宽
}

方法三:使用索引作为唯一标识(不推荐,会显示重复按钮)

如果需要保留重复的时间按钮,可以用数组索引作为ForEach的id,确保每个元素都被渲染:

ForEach(Array(dates.enumerated()), id: \.offset) { index, date in
    Button {
    } label: {
        // 按钮内容保持不变
        Capsule()
            .overlay {
                Text(text(for: date))
                    .foregroundStyle(.white)
            }
            .foregroundColor(.blue)
            .frame(height: 44)
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 04:11:03