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

SwiftUI:如何在模态视图导航栏按钮间添加居中标题

解决方案

要实现模态SwiftUI视图导航栏的左Cancel、右Done按钮,同时中间居中显示标题,有两种常用方案,以下是具体实现:

方案一:原生导航栏标题+工具栏按钮(推荐)

这是iOS14+的标准写法,利用原生导航栏的布局自动让标题居中在两个按钮之间:

import SwiftUI

struct BookingModal: View {
    @Environment(\.dismiss) var dismiss // iOS15+ 替代 presentationMode
    
    var body: some View {
        NavigationStack { // iOS16+ 使用 NavigationStack,iOS13-15 用 NavigationView
            VStack {
                Text("Hello World")
            }
            .navigationTitle("Booking")
            .navigationBarTitleDisplayMode(.inline) // 强制标题行内显示,确保居中
            .toolbar {
                // 左侧Cancel按钮
                ToolbarItem(placement: .navigationBarLeading) {
                    Button("Cancel") {
                        dismiss()
                    }
                }
                // 右侧Done按钮
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("Done") {
                        // 此处添加Done按钮的逻辑
                    }
                }
            }
        }
    }
}

struct BookingModal_Previews: PreviewProvider {
    static var previews: some View {
        BookingModal()
    }
}

如果需要兼容iOS13,可以使用旧版API:

.navigationBarTitle("Booking", displayMode: .inline)
.navigationBarItems(
    leading: Button("Cancel") { presentationMode.wrappedValue.dismiss() },
    trailing: Button("Done") { /* 逻辑 */ }
)

方案二:自定义居中标题(绝对居中场景)

如果原生标题因两侧按钮宽度差异导致视觉上不绝对居中,可以通过principal位置的ToolbarItem手动设置居中标题:

import SwiftUI

struct BookingModal: View {
    @Environment(\.dismiss) var dismiss
    
    var body: some View {
        NavigationStack {
            VStack {
                Text("Hello World")
            }
            .toolbar {
                // 居中标题
                ToolbarItem(placement: .principal) {
                    Text("Booking")
                        .font(.headline) // 匹配原生标题样式
                }
            }
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    Button("Cancel") { dismiss() }
                }
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button("Done") { /* 逻辑 */ }
                }
            }
        }
    }
}

错误原因说明

你之前尝试将所有元素放在leading的HStack中,会导致整个容器被限定在导航栏左侧区域,自然无法实现居中效果。正确的做法是将按钮分别指定到leading和trailing位置,标题通过原生导航栏标题或principal位置单独设置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 14:37:31