如何将导航栏按钮添加到选择器

Posted

技术标签:

【中文标题】如何将导航栏按钮添加到选择器【英文标题】:How to add a navigation bar button to a picker 【发布时间】:2020-08-26 05:28:04 【问题描述】:

如果所需选项不存在,用户应该能够向选择器添加新值。所以我基本上想用选项在视图中实现一个“添加”按钮。

我让它工作的唯一方法是向每个选项添加 .navigationBarItems 修饰符。但这似乎不仅是一种开销,而且如果列表的开头不包含任何选项,这也是一个问题(那么修饰符不会应用于任何元素,因此按钮不可见)。

我已经尝试了其他一些方法:

    将修饰符添加到 ForEach 会将所有选项合并到一个按钮中,因此无法再选择单个选项。 在 Picker 下方添加 EmptyView 并将修饰符附加到它会导致列表中出现额外的空行。

import SwiftUI

struct ContentView: View 
    @State private var selection = 1
    let options = [Option(title: "Option 1", id: 1), Option(title: "Option 2", id: 2)]
    
    struct Option 
        var title: String
        var id: Int
    

    var body: some View 
        NavigationView 
            Form 
                Picker("Test", selection: $selection) 
                    ForEach(options, id:\.id)  option in
                        Text(option.title).tag(option.id)
                        .navigationBarItems(trailing: Text("Add"))
                    
                    .navigationBarTitle("Options", displayMode: .inline)
                
                .navigationBarTitle("Form")
                .navigationBarItems(trailing: EmptyView())
            
        
    

【问题讨论】:

【参考方案1】:

即时更改 diaplayMode 总是会产生不希望的效果,但如果您有相同的效果(或选项没有),那么以下方法可以工作。

使用 Xcode 11.4 / ios 13.4 测试

struct ContentView: View 
    @State private var selection = 1
    @State private var options = [Option(title: "Option 1", id: 1), Option(title: "Option 2", id: 2)]

    struct Option 
        var title: String
        var id: Int
    

    var body: some View 
        NavigationView 
            Form 
                Picker("Test", selection: $selection) 
                    ForEach(options, id:\.id)  option in
                        self.optionRow(for: option)
                    
                    .listRowInsets(EdgeInsets(top: 1, leading: 1, bottom: 1, trailing: 1))
                
            
            .navigationBarTitle("Form")
//            .navigationBarTitle("Form", displayMode: .inline)
        
    

    @ViewBuilder
    func optionRow(for item: Option) -> some View 
        if item.id == selection 
            Text(item.title)
         else 
            Text(item.title)
                .navigationBarTitle("Options")
//                .navigationBarTitle("Options", displayMode: .inline)
                .navigationBarItems(trailing: Button("Add") 
                    // example of creating new option
                    self.options.append(Option(title: "Option 3", id: 3))
                )
        
    

【讨论】:

不改变显示模式是关键,你完全正确!几乎一切都按预期工作。我从您的解决方案中得到的第二件事是仅为当前未选择的选项设置 navigationBarTitle。再次感谢您的精彩回答。

以上是关于如何将导航栏按钮添加到选择器的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式添加到导航栏的UIBarButtonItem无法调用选择器,而添加到工具栏的按钮确实如此

如何在导航栏的标题项上添加专辑选择器视图

安卓案例:利用单选按钮实现底部导航栏

将级别选择器类添加到 wordpress 导航菜单

按下按钮并成功重定向到另一个页面后,如何禁用导航栏链接?

将微调器添加到 ActionBar(不是导航