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

SwiftUI中API返回文本的水平对齐布局问题求助

SwiftUI 实现带对齐编号的列表布局

我从API获取文本数据,希望在SwiftUI中展示。当前用HStack遍历SampleType数组生成带编号的文本,结果所有内容横向拥挤排列(对应截图绿色效果),想要实现每个编号与对应文本单独一行,且编号对齐的布局(对应截图红色效果)。测试代码及示例数据如下:

struct SampleTypeBox: View {
    
    var sampleType : [SampleTypeList]
    var body: some View {
        VStack(alignment: .leading,spacing: 20){
            HStack{
                ForEach(sampleType.indices,id:\.self){sample in
                    Text("\(sample+1)." + "\(sampleType[sample].SampleName)")
                        .font(.system(size: 13))
                        .foregroundColor(.green)
                }
            }
        }
    }
}

struct SampleTypeBox_Previews: PreviewProvider {
    static var previews: some View {
       let SampleList =
    [
        SampleTypeList(
            TestSampleTypeId: "50",
            SampleName: "2 ml Serum",
            ColourCode: "#FFB500"
        ),
        SampleTypeList(
            TestSampleTypeId: "55",
            SampleName: "EDTA Whole Blood",
            ColourCode: "#FFB500"
        ),
        SampleTypeList(
            TestSampleTypeId: "55",
            SampleName: "EDTA Whole Blood",
            ColourCode: "#FFB500"),
        SampleTypeList(
            TestSampleTypeId: "55",
            SampleName: "EDTA Whole Blood",
            ColourCode: "#FFB500"),
        SampleTypeList(
            TestSampleTypeId: "55",
            SampleName: "EDTA Whole Blood",
            ColourCode: "#FFB500")
        
    ]
        SampleTypeBox(sampleType: SampleList)
    }
}

struct SampleTypeList {
    var TestSampleTypeId: String
    var SampleName: String
    var ColourCode: String
}

解决方案

要实现每行独立且编号对齐的效果,核心调整两点:将外层横向布局改为纵向,同时给编号部分设置固定宽度保证对齐。修改后的完整代码如下:

struct SampleTypeBox: View {
    
    var sampleType : [SampleTypeList]
    
    var body: some View {
        VStack(alignment: .leading, spacing: 8) {
            ForEach(sampleType.indices, id: \.self) { index in
                HStack(alignment: .firstTextBaseline, spacing: 4) {
                    // 固定编号宽度,确保多位数也能对齐
                    Text("\(index + 1).")
                        .font(.system(size: 13))
                        .frame(width: 24, alignment: .leading)
                        .foregroundColor(.red)
                    
                    Text(sampleType[index].SampleName)
                        .font(.system(size: 13))
                        .foregroundColor(.red)
                }
            }
        }
        .padding()
    }
}

// 建议遵循Identifiable协议,优化遍历逻辑
struct SampleTypeList: Identifiable {
    let id = UUID()
    var TestSampleTypeId: String
    var SampleName: String
    var ColourCode: String
}

struct SampleTypeBox_Previews: PreviewProvider {
    static var previews: some View {
        let sampleList = [
            SampleTypeList(
                TestSampleTypeId: "50",
                SampleName: "2 ml Serum",
                ColourCode: "#FFB500"
            ),
            SampleTypeList(
                TestSampleTypeId: "55",
                SampleName: "EDTA Whole Blood",
                ColourCode: "#FFB500"
            ),
            SampleTypeList(
                TestSampleTypeId: "55",
                SampleName: "EDTA Whole Blood",
                ColourCode: "#FFB500"),
            SampleTypeList(
                TestSampleTypeId: "55",
                SampleName: "EDTA Whole Blood",
                ColourCode: "#FFB500"),
            SampleTypeList(
                TestSampleTypeId: "55",
                SampleName: "EDTA Whole Blood",
                ColourCode: "#FFB500")
        ]
        SampleTypeBox(sampleType: sampleList)
    }
}

关键说明

  • 外层用VStack替代HStack,让每个条目垂直排列,每行展示一组编号+文本
  • 给编号文本设置固定宽度frame(width: 24),确保1位、2位甚至多位数编号都能左对齐,避免错位
  • 调整spacing参数控制行间距和编号与文本的间距,优化视觉紧凑度
  • 让SampleTypeList遵循Identifiable协议,后续可直接遍历数组元素,代码更简洁安全

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 04:22:39