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

SwiftUI标尺实现:能否仅用一个ForEach?当前实现是否正确?

SwiftUI 标尺实现问题解答

问题一:是否可以仅用一个ForEach实现该标尺?

可以。核心思路是将所有刻度(大刻度+小刻度)统一纳入一个序列,通过判断每个刻度的索引类型(是否为大刻度)来渲染不同样式的刻度和数字,无需嵌套多层ForEach。

问题二:当前代码是否正确?

当前代码存在几个布局问题,无法完全匹配目标标尺效果:

  • 嵌套ForEach导致布局冗余,且内部Spacer会拉伸每个数字块的宽度,造成刻度间距不一致
  • 小刻度的padding(.bottom, -14)设置会导致刻度位置偏移,视觉上与大刻度不对齐
  • 数字位于大刻度右侧,不符合常见标尺数字在刻度下方的布局逻辑

优化后的单ForEach实现代码

struct Ruler: View {
    // 大刻度数量
    private let majorCount = 20
    // 每个大刻度间的小刻度数量
    private let minorPerMajor = 3
    // 总刻度数:大刻度数 + 大刻度数*小刻度数
    private var totalTicks: Int { majorCount * (minorPerMajor + 1) }
    // 刻度间距
    private let tickSpacing: CGFloat = 10
    
    var body: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            HStack(spacing: tickSpacing, alignment: .bottom) {
                ForEach(0..<totalTicks, id: \.self) { index in
                    // 判断是否为大刻度(每4个刻度一个大刻度:0,4,8...)
                    let isMajorTick = index % (minorPerMajor + 1) == 0
                    
                    VStack(alignment: .center, spacing: 4) {
                        // 绘制刻度线
                        Rectangle()
                            .fill(Color.white)
                            .frame(width: 1.5, height: isMajorTick ? 40 : 15)
                        
                        // 大刻度下方显示数字
                        if isMajorTick {
                            Text("\(index / (minorPerMajor + 1) + 1)")
                                .foregroundColor(.white)
                                .font(.system(size: 12, weight: .bold))
                        }
                    }
                }
            }
            .padding(.vertical, 8)
            .frame(height: 50)
            .background(Color.black)
        }
    }
}

struct Ruler_Previews: PreviewProvider {
    static var previews: some View {
        Ruler()
            .previewLayout(.sizeThatFits)
    }
}

代码说明

  • 通过计算总刻度数,用单个ForEach遍历所有刻度点
  • 根据索引判断是否为大刻度,分别渲染不同高度的刻度线
  • 将数字放在大刻度下方,符合标尺的常规布局
  • 统一设置刻度间距,保证所有刻度均匀分布
  • 移除冗余的嵌套布局和偏移设置,让布局更简洁可控

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 18:18:50