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

SwiftUI Grid布局文本框输入挤压元素问题求助

解决SwiftUI Grid中TextField扩张挤压布局的问题

核心问题原因

你遇到的问题是因为默认情况下TextField会根据输入内容自动调整宽度,而Grid组件没有明确的列宽约束,导致某列TextField内容过长时,会挤占其他列的空间,挤压Label和其他TextField。

解决方案1:给Grid定义固定列宽

通过GridColumn明确指定每列的宽度,约束Label列和TextField列的尺寸,避免布局混乱:

Grid(alignment: .center) {
    // 定义各列宽度:Label列设为灵活宽度,TextField列设为固定宽度
    GridColumn(width: .flexible(minimum: 150))
    GridColumn(width: .fixed(60))
    GridColumn(width: .fixed(60))
    GridColumn(width: .fixed(80))

    // Basic Empty Weight Row
    GridRow {
        Label("Basic Empty", systemImage: "")
            .labelStyle(.titleOnly)
            .padding(.horizontal, 10)
        
        TextField("W", text: $basicEmpW)
            .textFieldStyle(.roundedBorder)
            .multilineTextAlignment(.center)
        TextField("A", text: $basicEmpA)
            .textFieldStyle(.roundedBorder)
            .multilineTextAlignment(.center)
        TextField("MOM", text: $basicEmpMOM)
            .textFieldStyle(.roundedBorder)
            .multilineTextAlignment(.center)
    }

    // Pilot Row
    GridRow {
        Label("Pilot / Co-Pilot", systemImage: "star.fill")
            .padding(.horizontal, 10)
            .lineLimit(0)
        
        TextField("W", text: $pcpW)
            .textFieldStyle(.roundedBorder)
            .multilineTextAlignment(.center)
        TextField("A", text: $pcpA)
            .textFieldStyle(.roundedBorder)
            .multilineTextAlignment(.center)
        TextField("MOM", text: $pcpMOM)
            .textFieldStyle(.roundedBorder)
            .multilineTextAlignment(.center)
    }

    // Zero Fuel Weight Row
    GridRow {
        Label("Zero Fuel", systemImage: "gym.bag.fill")
        Label(zerofW, systemImage: "gym.bag.fill")
    }
}
.padding()

解决方案2:给TextField单独设置尺寸约束

如果不想修改Grid整体结构,可以直接给每个TextField添加固定宽度,并限制文本单行显示:

TextField("W", text: $basicEmpW)
    .frame(width: 60)
    .multilineTextAlignment(.center)
    .lineLimit(1)
    .truncationMode(.tail)

解决方案3:用LazyVStack+HStack模拟TableView布局

如果追求更贴近传统TableView的稳定性,可以放弃Grid,改用LazyVStack垂直排列行,每行用HStack分配元素宽度:

LazyVStack(spacing: 8) {
    // Basic Empty Weight Row
    HStack(alignment: .center, spacing: 16) {
        Label("Basic Empty", systemImage: "")
            .labelStyle(.titleOnly)
            .frame(width: 150, alignment: .leading)
            .padding(.horizontal, 10)
        
        TextField("W", text: $basicEmpW)
            .frame(width: 60)
            .textFieldStyle(.roundedBorder)
            .multilineTextAlignment(.center)
        TextField("A", text: $basicEmpA)
            .frame(width: 60)
            .textFieldStyle(.roundedBorder)
            .multilineTextAlignment(.center)
        TextField("MOM", text: $basicEmpMOM)
            .frame(width: 80)
            .textFieldStyle(.roundedBorder)
            .multilineTextAlignment(.center)
    }

    // Pilot Row
    HStack(alignment: .center, spacing: 16) {
        Label("Pilot / Co-Pilot", systemImage: "star.fill")
            .frame(width: 150, alignment: .leading)
            .padding(.horizontal, 10)
            .lineLimit(0)
        
        TextField("W", text: $pcpW)
            .frame(width: 60)
            .textFieldStyle(.roundedBorder)
            .multilineTextAlignment(.center)
        TextField("A", text: $pcpA)
            .frame(width: 60)
            .textFieldStyle(.roundedBorder)
            .multilineTextAlignment(.center)
        TextField("MOM", text: $pcpMOM)
            .frame(width: 80)
            .textFieldStyle(.roundedBorder)
            .multilineTextAlignment(.center)
    }

    // Zero Fuel Weight Row
    HStack(alignment: .center, spacing: 16) {
        Label("Zero Fuel", systemImage: "gym.bag.fill")
            .frame(width: 150, alignment: .leading)
        Label(zerofW, systemImage: "gym.bag.fill")
    }
}
.padding()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 01:15:35