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

SwiftUI中如何合并两个导航栏为一行并调整标题样式

问题解决:SwiftUI NavigationLink工具栏合并与导航标题滚动样式

一、解决工具栏叠加问题

你的问题根源是目标视图DisplayedInformationSettingsView额外嵌套了NavigationView,SwiftUI的NavigationLink是在父视图的NavigationView栈内完成页面跳转,目标视图无需重复包裹NavigationView,否则会导致两层导航栏叠加。

修改后的目标视图代码:

struct DisplayedInformationSettingsView: View {
    @ObservedObject var viewModel: CurrentWeatherViewModel
    @Environment(\.dismiss) var dismiss
    
    init(viewModel: CurrentWeatherViewModel = CurrentWeatherViewModel()) {
        self.viewModel = viewModel
    }
    
    var body: some View {
        List {
            Section(header: Text("Displayed Information")) {
                ForEach(viewModel.propertiesArray) { property in
                    HStack {
                        Toggle(isOn: Binding(
                            get: { property.info.isIncluded },
                            set: { newValue in
                                toggleProperty(property, newValue: newValue)
                            }
                        )) {
                            HStack {
                                Image(systemName: property.icon)
                                    .frame(width: 30)
                                Text(property.name)
                            }
                        }
                    }
                    .foregroundColor(property.info.isIncluded ? .primary : .secondary)
                }
                .onMove(perform: move)
            }
        }
        .toolbar {
            EditButton()
                .foregroundStyle(.primary)
        }
        .navigationTitle("Current Weather")
    }
    
    private func move(from source: IndexSet, to destination: Int) {
        viewModel.propertiesArray.move(fromOffsets: source, toOffset: destination)
    }
    
    private func toggleProperty(_ property: WeatherProperty, newValue: Bool) {
        if let index = viewModel.propertiesArray.firstIndex(where: { $0.name == property.name }) {
            viewModel.propertiesArray[index].info.isIncluded = newValue
        }
    }
}

修改说明:

  • 移除目标视图中的NavigationView,直接以List作为根视图
  • 调整初始化方法,优化预览和参数传递逻辑

父视图SettingsView无需修改,跳转后目标视图的工具栏会自动合并到父导航栈的工具栏中,不会再出现叠加问题。

二、实现导航标题滚动收缩样式

要让NavigationTitle在滚动时从大标题收缩为行内标题,只需给视图添加.navigationBarTitleDisplayMode(.large)配置,SwiftUI的可滚动容器(如List、ScrollView)会自动处理滚动时的标题样式变化。

父视图修改:

struct SettingsView: View {
    var body: some View {
        NavigationView {
            List {
                // 原有列表内容保持不变
            }
            .navigationTitle("Settings")
            .navigationBarTitleDisplayMode(.large) // 添加该行配置
        }
    }
}

目标视图修改:

在.navigationTitle后添加对应配置:

.toolbar {
    EditButton()
        .foregroundStyle(.primary)
}
.navigationTitle("Current Weather")
.navigationBarTitleDisplayMode(.large) // 添加该行配置

完成后,滚动List时大标题会自动收缩到导航栏内,实现类似系统设置的滚动标题效果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 05:43:30