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

SwiftUI如何使用Stack布局实现类似Bootstrap的双列非滚动表单

SwiftUI 双列表单实现问题

我正在尝试创建效果如下的表单:
目标表单效果
该表单使用Bootstrap制作十分简单,但我目前学习SwiftUI时最多只能实现如下效果:
当前实现效果
我尝试使用VStack、ZStack、HStack布局,但效果不符合预期,可能是使用方式有误,需要实现和Bootstrap版本相似的表单。
当前使用的SwiftUI代码如下:

struct FontsGroup: View {

@State var username: String = ""
@State var isPrivate: Bool = true


var body: some View {
    ZStack{
        VStack{
            HStack(
                alignment: .top,
                spacing: 0
            ) {
                
                Form{
                    Section(header:
                                HStack {
                        Text("Nurašoma Prekė")
                        Image(systemName: "staroflife.fill").foregroundColor(.red)
                        
                    }
                    ) {
                        TextField("Username", text: $username)
                        Toggle(isOn: $isPrivate) {
                            Text("Private Account")
                        }
                    }
                    
                }.listRowInsets(EdgeInsets())
                Form{
                    Section(header:
                                HStack {
                        Text("Nurašymo priežastis")
                        Image(systemName: "staroflife.fill").foregroundColor(.red)
                    }
                    ) {
                        TextField("Username", text: $username)
                        Toggle(isOn: $isPrivate) {
                            Text("Private Account")
                        }
                    }
                    
                }.listRowInsets(EdgeInsets())
            }
            HStack(
                alignment: .top,
                spacing: 0
            ) {
                
                Form{
                    Section(header:
                                HStack {
                        Text("Nurašoma Prekė")
                        Image(systemName: "staroflife.fill").foregroundColor(.red)
                        
                    }
                    ) {
                        TextField("Username", text: $username)
                        Toggle(isOn: $isPrivate) {
                            Text("Private Account")
                        }
                    }
                    
                }
                Form{
                    Section(header:
                                HStack {
                        Text("Nurašymo priežastis")
                        Image(systemName: "staroflife.fill").foregroundColor(.red)
                    }
                    ) {
                        TextField("Username", text: $username)
                        Toggle(isOn: $isPrivate) {
                            Text("Private Account")
                        }
                    }
                    
                }
            }
            
            
        }.padding()
    }
    
}  
}

我的目标是得到一个可配置任意行数的双列表单视图,另外我发现使用上述Stack布局时每个表单元素都可滚动,请问如何避免该问题?


解决方案

1. 解决单表单项滚动问题

SwiftUI的Form本质基于List实现,默认自带滚动特性。你嵌套了多个独立Form,才会出现每个表单项都可以独立滚动的问题,两种修复方案:

  • iOS 16+直接给每个Form添加.scrollDisabled(true)修饰符即可禁用滚动
  • 兼容更低版本可以直接弃用Form,用VStack+Section配合系统分组背景样式模拟表单效果,本身不具备滚动特性

2. 实现可配置双列表单

可以抽离表单项为通用组件,用LazyVGrid实现自动双列排布,仅需修改配置数组即可任意增减表单项数量,参考实现代码如下:

// 表单项类型枚举,可按需扩展选择器、日期选择等类型
enum FormFieldType {
    case text(Binding<String>)
    case toggle(Binding<Bool>)
}

// 表单项数据模型
struct FormField: Identifiable {
    let id = UUID()
    let title: String
    let required: Bool
    let type: FormFieldType
}

// 复用表单组件
struct FormItemView: View {
    let field: FormField
    var body: some View {
        Section {
            switch field.type {
            case .text(let bindStr):
                TextField("请输入", text: bindStr)
            case .toggle(let bindBool):
                Toggle(isOn: bindBool) {
                    Text("Private Account")
                }
            }
        } header: {
            HStack(spacing: 4) {
                Text(field.title)
                if field.required {
                    Image(systemName: "staroflife.fill")
                        .foregroundColor(.red)
                        .font(.caption)
                }
            }
        }
        .listRowInsets(.init(top: 8, leading: 12, bottom: 8, trailing: 12))
    }
}

// 最终双列表单视图
struct TwoColumnForm: View {
    // 按需配置表单项即可,自动适配双列换行
    private let fields: [FormField]
    @State private var field1 = ""
    @State private var toggle1 = true
    @State private var field2 = ""
    @State private var toggle2 = true
    @State private var field3 = ""
    @State private var toggle3 = true
    @State private var field4 = ""
    @State private var toggle4 = true
    
    init() {
        fields = [
            FormField(title: "Nurašoma Prekė", required: true, type: .text($field1)),
            FormField(title: "Nurašymo priežastis", required: true, type: .toggle($toggle1)),
            FormField(title: "Nurašoma Prekė", required: true, type: .text($field2)),
            FormField(title: "Nurašymo priežastis", required: true, type: .toggle($toggle2)),
            FormField(title: "Nurašoma Prekė", required: true, type: .text($field3)),
            FormField(title: "Nurašymo priežastis", required: true, type: .toggle($toggle3)),
            // 新增表单项会自动排布到下一行
        ]
    }
    
    var body: some View {
        ScrollView { // 整个表单需要滚动仅需在外层加一个ScrollView即可
            LazyVGrid(columns: [.init(.flexible(), spacing: 16), .init(.flexible(), spacing: 16)], spacing: 16) {
                ForEach(fields) { field in
                    VStack(spacing: 0) {
                        List {
                            FormItemView(field: field)
                        }
                        .listStyle(.grouped)
                        .scrollDisabled(true)
                        .frame(height: 120) // 可根据表单项高度自适应调整
                    }
                }
            }
            .padding()
        }
        .background(Color(UIColor.systemGroupedBackground))
    }
}

如果需要兼容iOS 15及更低版本,把LazyVGrid替换为每两个元素包一个HStack的分组逻辑即可实现同样效果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 11:18:01