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

SwiftUI中NavigationView内添加Form出现独立预览无法同屏

问题根因

这个表现不是预览故障,是NavigationView默认双栏布局的标准行为。
当NavigationView未指定导航样式时,在大屏设备、预览画布默认环境下会自动启用DoubleColumnNavigationViewStyle双栏模式:闭包内的第一个顶级子视图会被渲染为主栏/侧边栏,第二个顶级子视图会被渲染为独立的详情栏,两个栏位会被拆分到独立预览页展示,不会自动上下堆叠排列。
你的代码中NavigationView下直接放了两个平级顶级子视图:第一个是联系人List,第二个是设置Form,系统自然将Form识别为独立详情栏,单独占一个预览画布页。
另外原有代码存在逻辑bug:onChange监听showEmail变更后又主动调用showEmail.toggle(),会触发无限循环的状态更新,导致开关无法正常交互。

修复方案

如果需要将Form排列在联系人List的下方、同属一个页面,不要把Form作为NavigationView的平级顶级子视图,将两个视图嵌套在同一个垂直容器内,作为NavigationView的唯一主栏子视图即可,修正后代码如下:

@State var showEmail = false

var body: some View {
    NavigationView {
        // 主栏唯一根容器,包裹所有需要同页展示的内容
        VStack(spacing: 0) {
            List(contacts) { contact in
                NavigationLink(destination: DetailView(contact: contact)) {
                    ContactRow(showEmail: $showEmail, contact: contact)
                }
            }
            .listStyle(.insetGrouped)
            
            Form {
                Toggle("Show Email", isOn: $showEmail)
            }
            .frame(height: 60) // 手动限制Form高度,避免和List争抢滚动区域
        }
        .navigationTitle("Contacts")
    }
    // 若不需要适配大屏双栏布局,可加下面这行强制全设备使用单栏堆叠导航
    // .navigationViewStyle(.stack)
}

额外注意事项

  • 如果你的应用不需要支持iPad/横屏大屏的双栏导航,直接给NavigationView添加.navigationViewStyle(.stack)修饰符,强制所有场景使用单栏堆叠导航,从根源上避免栏位自动拆分的问题
  • Form本质是自带分组列表样式的滚动容器,和List同层放在垂直栈中时必须手动指定高度,否则两个滚动容器会出现高度计算异常
  • 必须删除原有onChange闭包中重复调用showEmail.toggle()的逻辑,否则会出现状态更新死循环

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 07:24:18