SwiftUI设置Sheet导航栏标题:使其位于Done按钮下方并占对应空间
解决方案
要实现Sheet导航栏标题居左且位于右上角Done按钮下方的布局,需要自定义导航栏的整体结构,打破SwiftUI默认导航栏的水平排列逻辑。以下是具体实现方案:
核心思路
隐藏默认导航栏标题,通过自定义Toolbar完全控制导航栏区域的布局,将Done按钮和标题垂直排列:按钮固定在右上角,标题居左并占据按钮下方的全部空间,同时支持动态文本的滚动或换行需求。
代码实现
版本1:标题过长时横向滚动
struct CustomSheetView: View { @Environment(\.dismiss) private var dismiss let dynamicTitle: String var body: some View { NavigationStack { // Sheet的主内容 Text("Sheet Content Area") .navigationTitle("") // 隐藏默认标题 .toolbar { ToolbarItem(placement: .navigationBar) { VStack(alignment: .leading, spacing: 8) { // 右上角的Done按钮 HStack { Spacer() Button("Done") { dismiss() } .foregroundColor(.blue) } // 居左的可滚动标题 ScrollView(.horizontal, showsIndicators: false) { Text(dynamicTitle) .font(.headline) .lineLimit(1) } .frame(maxWidth: .infinity, alignment: .leading) } .padding(.horizontal, 16) .padding(.vertical, 8) } } } } }
版本2:标题过长时自动换行
如果需要标题换行而非滚动,只需调整标题部分的代码:
// 替换版本1中的ScrollView部分 Text(dynamicTitle) .font(.headline) .lineLimit(nil) // 允许自动换行 .frame(maxWidth: .infinity, alignment: .leading)
关键细节说明
- 使用
ToolbarItem(placement: .navigationBar)接管整个导航栏区域,而非默认的分段布局。 - 通过
HStack + Spacer将Done按钮固定在右上角,确保不与标题水平对齐。 - 标题的
frame(maxWidth: .infinity, alignment: .leading)设置让其居左并占据按钮下方的全部可用空间,满足"覆盖Done按钮下方空间"的需求。 - 动态文本的处理:横向滚动版本用
ScrollView(.horizontal)配合lineLimit(1)实现单行滚动;换行版本则移除ScrollView,设置lineLimit(nil)允许文本自动换行。
内容的提问来源于stack exchange,提问作者tech_human
相关产品推荐
相关产品推荐

