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
相关产品推荐
相关产品推荐

