SwiftUI导航栏工具栏项位置过高,如何移至栏底部?
SwiftUI导航栏工具栏项底部对齐解决方案
问题描述
我通过NavigationLink打开一个SwiftUI视图,代码如下:
struct UserSettingsView: View { @Environment(\.presentationMode) var presentationMode var body: some View { ZStack { Color("navbar_2280DA").ignoresSafeArea(.all) Image("profile_background") .resizable() .aspectRatio(contentMode: .fill) .ignoresSafeArea(.all) } .navigationBarBackButtonHidden(true) .toolbar { ToolbarItem(placement: .topBarLeading) { VStack { Spacer() HStack { Button { presentationMode.wrappedValue.dismiss() } label: { Image("btn_arrow_back") } Spacer() } } } } .toolbar { ToolbarItem(placement: .principal) { Text("Settings") .font(.custom("Poppins-Medium", size: 22)) .kerning(1.76) } } .toolbarBackground(Color("navbar_2280DA"), for: .navigationBar) .toolbarBackground(.visible, for: .navigationBar) } }
视图整体显示正常,但导航栏上的工具栏项位置过高。我尝试用VStack调整返回按钮位置,但效果甚微,希望能更精准控制(比如给栏底部添加约束内边距),且不想自定义导航栏,要使用iOS默认导航栏UI,请教如何将工具栏项移至导航栏底部?
解决方案
以下两种方案都基于iOS默认导航栏实现,无需自定义导航栏即可精准控制工具栏项的底部对齐:
方案一:内边距+占高对齐(简单直接)
给工具栏控件添加底部内边距,同时让控件占满导航栏的高度,强制内容贴到底部:
struct UserSettingsView: View { @Environment(\.presentationMode) var presentationMode var body: some View { ZStack { Color("navbar_2280DA").ignoresSafeArea(.all) Image("profile_background") .resizable() .aspectRatio(contentMode: .fill) .ignoresSafeArea(.all) } .navigationBarBackButtonHidden(true) .toolbar { ToolbarItem(placement: .topBarLeading) { Button { presentationMode.wrappedValue.dismiss() } label: { Image("btn_arrow_back") } .frame(maxHeight: .infinity, alignment: .bottom) // 占满导航栏高度,底部对齐 .padding(.bottom, 8) // 调整底部内边距,适配需求 } } .toolbar { ToolbarItem(placement: .principal) { Text("Settings") .font(.custom("Poppins-Medium", size: 22)) .kerning(1.76) .frame(maxHeight: .infinity, alignment: .bottom) .padding(.bottom, 8) } } .toolbarBackground(Color("navbar_2280DA"), for: .navigationBar) .toolbarBackground(.visible, for: .navigationBar) } }
方案二:自定义对齐指南(精准统一)
通过扩展对齐规则,统一控制所有工具栏项的底部对齐,适合需要批量调整多个元素的场景:
// 先扩展自定义对齐规则 extension VerticalAlignment { private enum NavBarBottom: AlignmentID { static func defaultValue(in context: ViewDimensions) -> CGFloat { context[.bottom] } } static let navBarBottom = VerticalAlignment(NavBarBottom.self) } struct UserSettingsView: View { @Environment(\.presentationMode) var presentationMode var body: some View { ZStack { Color("navbar_2280DA").ignoresSafeArea(.all) Image("profile_background") .resizable() .aspectRatio(contentMode: .fill) .ignoresSafeArea(.all) } .navigationBarBackButtonHidden(true) .toolbar { ToolbarItem(placement: .topBarLeading) { Button { presentationMode.wrappedValue.dismiss() } label: { Image("btn_arrow_back") } .alignmentGuide(.navBarBottom) { $0[.bottom] } } } .toolbar { ToolbarItem(placement: .principal) { Text("Settings") .font(.custom("Poppins-Medium", size: 22)) .kerning(1.76) .alignmentGuide(.navBarBottom) { $0[.bottom] } } } .toolbarBackground(Color("navbar_2280DA"), for: .navigationBar) .toolbarBackground(.visible, for: .navigationBar) .alignmentGuide(.navBarBottom) { $0[.bottom] } } }
内容的提问来源于stack exchange,提问作者Eugene Alexeev
相关产品推荐
相关产品推荐

