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

时间:2020-08-26 05:28:04

标签: swiftui

如果所需选项还不存在,则用户应该能够向选择器添加新值。因此,我基本上想为带有选项的视图实现一个“添加”按钮。

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

我已经尝试了其他几件事:

  1. 在ForEach中添加修饰符会将所有选项合并为一个按钮,因此不再可以选择单个选项。
  2. 添加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 个答案:

答案 0 :(得分:1)

动态更改diaplayMode总是会产生不希望有的效果,但是如果您使用相同的选项(对于Option而言却没有),则可以使用以下方法。

通过Xcode 11.4 / iOS 13.4测试

demo

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))
                })
        }
    }
}