将分段样式选择器添加到 SwiftUI 的 NavigationView

Far*_*ruk 8 picker navigationbar swift navigationview swiftui

问题和标题一样简单。我正在尝试将Picker具有SegmentedPickerStyleto样式的 aNavigationBar放入SwiftUI. 它就像本机Phone应用程序的历史记录页面。图片在下面

在此处输入图片说明

我曾在 Google 和 Github 上寻找过例如项目、库或任何教程,但都没有找到。我认为如果 nativa 应用程序和 WhatsApp 例如有它,那么它应该是可能的。任何帮助,将不胜感激。

Fry*_*Fry 11

您可以将 Picker 直接放入 .navigationBarItems。

在此处输入图片说明

我遇到的唯一麻烦是让 Picker 居中。(只是为了表明 Picker 确实可以在导航栏中,我将一种带有框架和几何阅读器的 hacky 解决方案放在一起。您需要找到一个适当的居中解决方案。)

struct ContentView: View {
    @State private var choices = ["All", "Missed"]
    @State private var choice = 0

    @State private var contacts = [("Anna Lisa Moreno", "9:40 AM"), ("Justin Shumaker", "9:35 AM")]

    var body: some View {
        GeometryReader { geometry in
            NavigationView {
                List {
                    ForEach(self.contacts, id: \.self.0) { (contact, time) in
                        ContactView(name: contact, time: time)
                    }
                    .onDelete(perform: self.deleteItems)
                }
                .navigationBarTitle("Recents")
                .navigationBarItems(
                    leading:
                    HStack {
                        Button("Clear") {
                            // do stuff
                        }
                        Picker(selection: self.$choice, label: Text("Pick One")) {
                            ForEach(0 ..< self.choices.count) {
                                Text(self.choices[$0])
                            }
                        }
                        .frame(width: 130)
                        .pickerStyle(SegmentedPickerStyle())
                            .padding(.leading, (geometry.size.width / 2.0) - 130)
                    },
                trailing: EditButton())
            }
        }
    }

    func deleteItems(at offsets: IndexSet) {
        contacts.remove(atOffsets: offsets)
    }

}

struct ContactView: View {
    var name: String
    var time: String

    var body: some View {
        HStack {
            VStack {
                Image(systemName: "phone.fill.arrow.up.right")
                .font(.headline)
                .foregroundColor(.secondary)
                Text("")
            }
            VStack(alignment: .leading) {
                Text(self.name)
                    .font(.headline)
                Text("iPhone")
                    .foregroundColor(.secondary)
            }
            Spacer()
            Text(self.time)
                .foregroundColor(.secondary)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


hst*_*tdt 10

SwiftUI 2 + 工具栏:

struct DemoView: View {

    @State private var mode: Int = 0

    var body: some View {
        Text("Hello, World!")
            .toolbar {
                ToolbarItem(placement: .principal) {
                    Picker("Color", selection: $mode) {
                        Text("Light").tag(0)
                        Text("Dark").tag(1)
                    }
                    .pickerStyle(SegmentedPickerStyle())
                }
            }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 对于任何想要“Picker”使用其“固有内容大小/理想大小”的人,只需对其应用“.fixedSize()”修饰符即可。 (5认同)

Far*_*ruk 6

对于那些想要使其成为死点的人,只需HStack在每侧放两个并使它们的宽度固定且相等。

将此方法添加到View扩展中。

extension View {
    func navigationBarItems<L, C, T>(leading: L, center: C, trailing: T) -> some View where L: View, C: View, T: View {
        self.navigationBarItems(leading:
            HStack{
                HStack {
                    leading
                }
                .frame(width: 60, alignment: .leading)
                Spacer()
                HStack {
                    center
                }
                 .frame(width: 300, alignment: .center)
                Spacer()
                HStack {
                    //Text("asdasd")
                    trailing
                }
                //.background(Color.blue)
                .frame(width: 100, alignment: .trailing)
            } 
            //.background(Color.yellow)
            .frame(width: UIScreen.main.bounds.size.width-32)
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

现在你有一个View modifiernavigationBatItems(:_). 您可以根据需要编辑代码。

用法示例:

.navigationBarItems(leading: EmptyView(), center:       
    Picker(selection: self.$choice, label: Text("Pick One")) {
        ForEach(0 ..< self.choices.count) {
             Text(self.choices[$0])
        }
     }
    .pickerStyle(SegmentedPickerStyle())
}, trailing: EmptyView())
Run Code Online (Sandbox Code Playgroud)

更新

有问题leading和尾随项目被侵犯UINavigationBarContentViewsafeArea。在我搜索时,我在这个答案中遇到了另一个解决方案。它是一个名为SwiftUIX 的小助手库。如果你不想安装整个图书馆般的我-我创建了一个要点只是为了navigationBarItems。只需将文件添加到您的项目中。

但是不要忘记这一点,它被拉伸Picker以覆盖所有可用空间并迫使StatusView其变窄。所以我不得不设置这样的框架;

.navigationBarItems(center:
    Picker(...) {
        ...
    }
    .frame(width: 150)
, trailing:
    StatusView()
    .frame(width: 70)
)
Run Code Online (Sandbox Code Playgroud)