SwiftUI可编辑的导航栏标题

5

是否可以使SwiftUI的导航标题可编辑? 不幸的是,navigationTitle修饰符只接受Text视图而不是TextField视图。 我想这样做,而不仅仅是在导航栏下使用文本字段,因为我仍然希望在用户向下滚动时出现修改后的标题,并且无论您是否定义了标题,导航栏都会分配空间给导航标题。

2个回答

5

iOS/iPadOS 16+,macOS 13+

现在navigationTitle修饰符接受一个Binding<String>参数,以及通常的基于String的初始化器。

当使用绑定值并且导航栏处于内联形式时,标题会带有一个下拉菜单,其中包含一个重命名选项。 点击此选项允许用户编辑该视图的标题:

struct EditableTitleView: View {
    @State private var title = "View Title"

    var body: some View {
        Text("Editable Title View")
            .navigationTitle($title)
            .navigationBarTitleDisplayMode(.inline)
    }
}

虽然这不完全与始终使用文本字段相同的用户体验一致,但由于它是标准的SwiftUI实现,所以更容易实现。

iOS 16中带有绑定值的导航标题的实现

对于早期版本的iOS

您可以通过指定ToolbarItem并将其放置在可能预期的标题位置上来在NavigationView中放置自定义视图,例如下面的代码。我添加了RoundedBorderTextFieldStyle以使文本字段更可见:

struct EditableTitleView: View {
  @State private var editableTitle: String = "My Title"
    var body: some View {
      NavigationView {
        Text("View with editable title")
          .toolbar {
            ToolbarItem(placement: .principal) {
              TextField("Title", text: $editableTitle)
                .textFieldStyle(RoundedBorderTextFieldStyle())
            }
          }
      }
    }
}

请注意,如果您在视图中添加了navigationTitle修饰符,它的默认大型样式在iOS上仍将显示在工具栏下方,但如果它从页面滚动出去,则会消失,而您的主要项目将保持在屏幕上。 如果设置.navigationBarTitleDisplayMode(.inline),则较大的标题样式永远不会显示。
我提到这点是因为您应该考虑为您的视图保留标题,有几个原因:
  • 如果NavigationLink将视图推入堆栈,您希望在返回按钮和长按时显示堆叠视图列表中的有意义名称。
  • 我还没有检查当您没有标题的导航子视图时VoiceOver会发生什么。 覆盖本机行为越多,您就需要考虑是否使您的应用程序比SwiftUI默认提供的更难访问。

示例TextField在标题栏中的屏幕截图


有没有办法在下拉菜单中添加更多选项?假设我想在“重命名(/)”旁边添加“删除(X)”。这可行吗? - undefined
在.toolbar修饰符中,您可以添加一个ToolbarTitleMenu块(请参阅https://developer.apple.com/documentation/swiftui/toolbartitlemenu)。这将覆盖默认菜单,该菜单仅包含重命名选项 - 您可以通过在ToolbarTitleMenu中指定RenameButton()来将其添加到自己的菜单中。 - undefined

2
尝试在工具栏的主要位置中使用 ToolbarItem 中的 TextField。创建一个计算属性作为目标,并给它一个可编辑的导航标题。请参考下图所示: TextField Navigation Title
struct TextFieldNavigationTitleView: View {
    @State var mainTitle = "Main Menu"
    @State var areaOneTitle = "Area One"

    var body: some View {
        NavigationView {
            NavigationLink("App Area One", destination: areaOne)
            .toolbar {
                ToolbarItem(placement: .principal) {
                    TextField("Navigation Title", text: $mainTitle)
                }
            }
        }
    }
    
    var areaOne : some View {
        Text("AREA ONE")
            .toolbar {
                ToolbarItem(placement: .principal) {
                    TextField("Area One Title", text: $areaOneTitle)
                }
            }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接