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

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

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

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

  1. 将修饰符添加到 ForEach 会将所有选项合并到一个按钮中,因此无法再选择单个选项。
  2. 在 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())
            }
        }
    }
}

【问题讨论】:

    标签: swiftui


    【解决方案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。再次感谢您的精彩回答。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多