swiftui-picker不显示选定的值

发布于 2025-02-04 19:52:51 字数 972 浏览 4 评论 0原文

初始位置:从数据库中填充两个选择器,其中第二个取决于第一个。我遵循此从上一个挑选器-CoreData/swiftui picker值示例,并且效果很好。 只有一个问题:第二个选择器未显示所选值。

    @State var courtSelected = 0
    @State var judgeSelected = 0

HStack{
    Picker(selection: $courtSelected, label: Text("Gericht \(courtSelected)")){
        ForEach(0..<courts.count){ court in
            Text("\(courts[court].name ?? "Unknown")")
        }
    }
}
HStack {
    Picker(selection: $judgeSelected, label: Text("Richter: (\(judgeSelected))")){
        ForEach(Array(courts[courtSelected].courtsJudges! as! Set<Judges>), id: \.self) { judge in
            Text("\(judge.gender ?? "") \(judge.title ?? "") \(judge.name ?? "")")
        }
    }
}

仅差异:

  1. 从NSSET到数组的修改
  2. 我必须更改@binding var judgeselectected:int to @state,因为否则我必须将选择从App sctruct开始的参数选择作为参数。

在标签中打印$ judgessel的$ judgesselect示出了此VAR永远不会更改。

Initial position: making two pickers filled from database where the second depends on the first. I followed this Picker Values from a previous picker - CoreData/SwiftUI example and it works pretty good.
Only one problem: the second picker doesn't show the selected value.

    @State var courtSelected = 0
    @State var judgeSelected = 0

HStack{
    Picker(selection: $courtSelected, label: Text("Gericht \(courtSelected)")){
        ForEach(0..<courts.count){ court in
            Text("\(courts[court].name ?? "Unknown")")
        }
    }
}
HStack {
    Picker(selection: $judgeSelected, label: Text("Richter: (\(judgeSelected))")){
        ForEach(Array(courts[courtSelected].courtsJudges! as! Set<Judges>), id: \.self) { judge in
            Text("\(judge.gender ?? "") \(judge.title ?? "") \(judge.name ?? "")")
        }
    }
}

Only differences:

  1. the modification from NSSet to array
  2. I had to change @Binding var judgeSelected:Int to @State, because otherwise I have to hand over the judge selected as Parameter beginning from App-Struct.

Printing the $judgeSelected inside the label demonstrates, that this var is never changed.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

感情旳空白 2025-02-11 19:52:51

您的选择和演示文稿的类型有所不同,因此请添加标签:

Picker(selection: $courtSelected, label: Text("Gericht \(courtSelected)")){
    ForEach(0..<courts.count){ court in
        Text("\(courts[court].name ?? "Unknown")").tag(court)  // << here !!
    }
}

第二个Picker Presents对象,因此选择也应该是一个对象,例如

@State var judgeSelected: Judges? = nil

接下来显示类似的情况,因此应有用 https://stackoverflow.com/a/a/68815871/12299030

Your selection and presentation are differ by type, so add tag:

Picker(selection: $courtSelected, label: Text("Gericht \(courtSelected)")){
    ForEach(0..<courts.count){ court in
        Text("\(courts[court].name ?? "Unknown")").tag(court)  // << here !!
    }
}

Second picker presents objects, so selection should also be an object, like

@State var judgeSelected: Judges? = nil

Next shows similar case so should be helpful https://stackoverflow.com/a/68815871/12299030

未蓝澄海的烟 2025-02-11 19:52:51

尝试这样的事情:

    HStack{
        Picker(selection: $courtSelected, label: Text("Gericht \(courtSelected)")){
            ForEach(0..<courts.count){ court in
                Text("\(courts[court].name ?? "Unknown")")
            }
        }
    }
    HStack {
        Picker(selection: $judgeSelected, label: Text("Richter: (\(judgeSelected))")){
            // -- here
            ForEach(Array(Set(courts[courtSelected].courtsJudges!)), id: \.self) { judge in  
                Text("\(judge.gender ?? "") \(judge.title ?? "") \(judge.name ?? "")")
            }
        }.id(UUID())   // <-- here
    }
}

还请注意第二个使用 set 的的。 PS,请勿使用强制解开,即。您的代码中没有

edit-1:为了避免使用arrayliteral的错误,请尝试以下:

    HStack {
        Picker(selection: $judgeSelected, label: Text("Richter: (\(judgeSelected))")){
            if let theJudges = courts[courtSelected].courtsJudges {
                ForEach(Array(Set(theJudges)), id: \.self) { judge in
                    Text("\(judge.gender ?? "") \(judge.title ?? "") \(judge.name ?? "")")
                }
            }
        }.id(UUID())
    }

edit-2:

这是我的测试代码,允许第二个选择器
取决于第一个选择器。我同时使用了id标记和标签
必须匹配选择类型。

由于您没有显示法院法官的结构代码,
我为这些创建了一些示例结构。
您将必须调整代码以适合您的结构

使用 struct struct的id在第二个挑选器中的tag中使用。
但是,还有其他方法可以使用int标签,例如使用数组索引,例如:

struct Judge: Identifiable, Hashable {
    var id: Int
    var gender: String?
    var name: String?
    var title: String?
}

struct Court: Identifiable, Hashable {
    var id: Int
    var name: String?
    var courtsJudges: [Judge]?
}

struct ContentView: View {
    @State var courtSelected = 0
    @State var judgeSelected = 0
    
    @State var courts: [Court] = [
        Court(id: 0, name: "one",
              courtsJudges: [
                Judge(id: 0, gender: "Male", name: "name1", title: "title1"),
                Judge(id: 1, gender: "Male", name: "name2", title: "title2"),
                Judge(id: 2, gender: "Male", name: "name3", title: "title3")
              ]),
        Court(id: 1, name: "two",
              courtsJudges: [
                Judge(id: 3, gender: "Female", name: "name7", title: "title7"),
                Judge(id: 4, gender: "Female", name: "name8", title: "title8"),
                Judge(id: 5, gender: "Female", name: "name9", title: "title9")
              ])
    ]

    var body: some View {
        VStack (spacing: 77) {
            HStack{
                Picker(selection: $courtSelected, label: Text("Gericht \(courtSelected)")){
                    ForEach(0..<courts.count) { court in
                        Text("\(courts[court].name ?? "Unknown")").tag(court)
                    }
                }
            }
            HStack {
                Picker(selection: $judgeSelected, label: Text("Richter: (\(judgeSelected))")){
                    if let theJudges = courts[courtSelected].courtsJudges {
                        ForEach(Array(Set(theJudges))) { judge in
                            Text("\(judge.gender ?? "") \(judge.title ?? "") \(judge.name ?? "")")
                                .tag(judge.id)
                        }
                    }
                }.id(UUID())
            }
        }.padding()
    }
}

替代::

 HStack {
     Picker(selection: $judgeSelected, label: Text("Richter: (\(judgeSelected))")){
         if let theJudges = courts[courtSelected].courtsJudges, let arr = Array(Set(theJudges)) {
             ForEach(arr.indices, id: \.self) { index in
                 Text("\(arr[index].gender ?? "") \(arr[index].title ?? "") \(arr[index].name ?? "")")
                     .tag(index)
             }
         }
     }.id(UUID())
 }

try something like this:

    HStack{
        Picker(selection: $courtSelected, label: Text("Gericht \(courtSelected)")){
            ForEach(0..<courts.count){ court in
                Text("\(courts[court].name ?? "Unknown")")
            }
        }
    }
    HStack {
        Picker(selection: $judgeSelected, label: Text("Richter: (\(judgeSelected))")){
            // -- here
            ForEach(Array(Set(courts[courtSelected].courtsJudges!)), id: \.self) { judge in  
                Text("\(judge.gender ?? "") \(judge.title ?? "") \(judge.name ?? "")")
            }
        }.id(UUID())   // <-- here
    }
}

Note also the second ForEach with Set. PS, do not use forced unwrap, ie. no ! in your code.

EDIT-1: to avoid the error with arrayLiteral, try this:

    HStack {
        Picker(selection: $judgeSelected, label: Text("Richter: (\(judgeSelected))")){
            if let theJudges = courts[courtSelected].courtsJudges {
                ForEach(Array(Set(theJudges)), id: \.self) { judge in
                    Text("\(judge.gender ?? "") \(judge.title ?? "") \(judge.name ?? "")")
                }
            }
        }.id(UUID())
    }

EDIT-2:

here is my test code that allows the second picker
to depend on the first picker. I used both the id marker, and tag that
must match the selection type.

Since you don't show your struct code for court and judge,
I created some example structs for those.
You will have to adjust the code to cater for your structs.

Used the id of the Judge struct in the second picker for the tag.
However, there are other ways to have a Int tag, for example using array indices, such as:

struct Judge: Identifiable, Hashable {
    var id: Int
    var gender: String?
    var name: String?
    var title: String?
}

struct Court: Identifiable, Hashable {
    var id: Int
    var name: String?
    var courtsJudges: [Judge]?
}

struct ContentView: View {
    @State var courtSelected = 0
    @State var judgeSelected = 0
    
    @State var courts: [Court] = [
        Court(id: 0, name: "one",
              courtsJudges: [
                Judge(id: 0, gender: "Male", name: "name1", title: "title1"),
                Judge(id: 1, gender: "Male", name: "name2", title: "title2"),
                Judge(id: 2, gender: "Male", name: "name3", title: "title3")
              ]),
        Court(id: 1, name: "two",
              courtsJudges: [
                Judge(id: 3, gender: "Female", name: "name7", title: "title7"),
                Judge(id: 4, gender: "Female", name: "name8", title: "title8"),
                Judge(id: 5, gender: "Female", name: "name9", title: "title9")
              ])
    ]

    var body: some View {
        VStack (spacing: 77) {
            HStack{
                Picker(selection: $courtSelected, label: Text("Gericht \(courtSelected)")){
                    ForEach(0..<courts.count) { court in
                        Text("\(courts[court].name ?? "Unknown")").tag(court)
                    }
                }
            }
            HStack {
                Picker(selection: $judgeSelected, label: Text("Richter: (\(judgeSelected))")){
                    if let theJudges = courts[courtSelected].courtsJudges {
                        ForEach(Array(Set(theJudges))) { judge in
                            Text("\(judge.gender ?? "") \(judge.title ?? "") \(judge.name ?? "")")
                                .tag(judge.id)
                        }
                    }
                }.id(UUID())
            }
        }.padding()
    }
}

Alternatively:

 HStack {
     Picker(selection: $judgeSelected, label: Text("Richter: (\(judgeSelected))")){
         if let theJudges = courts[courtSelected].courtsJudges, let arr = Array(Set(theJudges)) {
             ForEach(arr.indices, id: \.self) { index in
                 Text("\(arr[index].gender ?? "") \(arr[index].title ?? "") \(arr[index].name ?? "")")
                     .tag(index)
             }
         }
     }.id(UUID())
 }
夏至、离别 2025-02-11 19:52:51

首先:感谢迄今为止的所有大力帮助。

直到现在将所有内容都结合在一起。

以下代码会创建一个选择器,但未显示选择。更改为放射线,您无法选择任何东西。

这是我的编辑代码

struct ContentView: View {
    @Environment(\.managedObjectContext) private var viewContext
    
    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Courts.name, ascending: true)],
        animation: .default
    )
    private var courts: FetchedResults<Courts>
    
    @State var courtSelected = 0
    @State var judgeSelected = 0
    
    var body: some View {
        HStack{
            Picker(selection: $courtSelected, label: Text("Gericht")){
                ForEach(0..<courts.count){ court in
                    Text("\(courts[court].name ?? "Unknown")").tag(court)
                }
            }
        }
        HStack {
            Picker(selection: $judgeSelected, label: Text("Richter \(judgeSelected)")){
                ForEach(Array(courts[courtSelected].courtsJudges as! Set<Judges>), id: \.self) { judge in
                    Text("\(judge.gender ?? "") \(judge.title ?? "") \(judge.name ?? "")").tag(judge)
                }
            }.id(UUID())
        }
    }
}

“上面的代码无需选择” “上面的代码为radiobuttons”

下一个代码仍然会导致错误

HStack {
    Picker(selection: $judgeSelected, label: Text("Richter: (\(judgeSelected))")){
        if let theJudges = courts[courtSelected].courtsJudges {
            ForEach(Array(Set(theJudges)), id: \.self) { judge in
                Text("\(judge.gender ?? "") \(judge.title ?? "") \(judge.name ?? "")")
            }
        }
    }.id(UUID())
}

net/3yq36.jpg“ rel =“ nofollow noreferrer 要去其他任何地方,因为一开始就没有显示任何东西,并且收音机是灰色的。

是,因为选择器2取决于选择器1,并且当选择了Picker 1中的值时会更改?

这全都用于XCode 13.4.1上的MacOS

First: thanks for all the great help so far.

Bringing it all together til now.

The following code creates a picker, but the selection is not shown. Changing to a radioGroup, you can't select anything.

Here's my edited code

struct ContentView: View {
    @Environment(\.managedObjectContext) private var viewContext
    
    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Courts.name, ascending: true)],
        animation: .default
    )
    private var courts: FetchedResults<Courts>
    
    @State var courtSelected = 0
    @State var judgeSelected = 0
    
    var body: some View {
        HStack{
            Picker(selection: $courtSelected, label: Text("Gericht")){
                ForEach(0..<courts.count){ court in
                    Text("\(courts[court].name ?? "Unknown")").tag(court)
                }
            }
        }
        HStack {
            Picker(selection: $judgeSelected, label: Text("Richter \(judgeSelected)")){
                ForEach(Array(courts[courtSelected].courtsJudges as! Set<Judges>), id: \.self) { judge in
                    Text("\(judge.gender ?? "") \(judge.title ?? "") \(judge.name ?? "")").tag(judge)
                }
            }.id(UUID())
        }
    }
}

Code above leads to no selectioncode above as radioButtons

The next code still leads to an error

HStack {
    Picker(selection: $judgeSelected, label: Text("Richter: (\(judgeSelected))")){
        if let theJudges = courts[courtSelected].courtsJudges {
            ForEach(Array(Set(theJudges)), id: \.self) { judge in
                Text("\(judge.gender ?? "") \(judge.title ?? "") \(judge.name ?? "")")
            }
        }
    }.id(UUID())
}

Code showing error

I think, the problem has to be anywhere else, because already at the start the picker doesn't show anything and the radios are grey.

Is it, because picker 2 depends on picker 1 and changes when a value in picker 1 is selected?

It's all for macOS on xcode 13.4.1

£噩梦荏苒 2025-02-11 19:52:51

我创建了一个具有核心数据的完整新项目,添加了两个实体(法院和法官),每个实体都有两个属性(ID和名称)。

然后我只做出了这个观点:

import SwiftUI
import CoreData

struct ContentView: View {
    @Environment(\.managedObjectContext) private var viewContext
    
    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Courts.name, ascending: true)],
        animation: .default
    )
    private var courts: FetchedResults<Courts>
    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Judges.name, ascending: true)],
        animation: .default
    )
    private var judges: FetchedResults<Judges>
    
    @State var courtSelected = 0
    @State var judgeSelected = 0
    
    var body: some View {
        if(courts.count > 0) {
            HStack{
                Picker(selection: $courtSelected, label: Text("Gericht")){
                    ForEach(0..<courts.count){ court in
                        Text("\(courts[court].name ?? "Unknown")").tag(court)
                    }
                }
            }
            HStack {
                Picker(selection: $judgeSelected, label: Text("Richter \(judgeSelected)")){
                    ForEach(Array(courts[courtSelected].courtsJudges as! Set<Judges>), id: \.self) { judge in
                        Text("\(judge.name ?? "")").tag(judge)
                    }
                }.id(UUID())
            }
            HStack {
                Button("neue Gerichte") {
                    addItem()
                    addJudges()
                }
            }
        }
    }
    
    private func addItem() {
        for id in 0..<3 {
            let newItem = Courts(context: viewContext)
            newItem.id = UUID()
            newItem.name = "Gericht Nr. \(id)"
            
            
            do {
                try viewContext.save()
            } catch {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                let nsError = error as NSError
                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
            }
        }
        
    }
    
    
    private func addJudges() {
        for cd in 0..<courts.count {
            for jd  in 0..<3 {
                let newJudge = Judges(context: viewContext)
                newJudge.id = UUID()
                newJudge.name = "Richter \(jd) am Gericht \(courts[cd].name)"
                newJudge.judgesCourts = courts[cd]
                
                try? viewContext.save()
            }
        }
    }
    
}

结果:两个采摘者都可以,第一个ist还可以,第二个显示正确的法官,但它们不是“可选”的。

I created a complete new project with core data, added two entities (Courts and Judges) with two attributes each (id and name).

Then I only made this view:

import SwiftUI
import CoreData

struct ContentView: View {
    @Environment(\.managedObjectContext) private var viewContext
    
    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Courts.name, ascending: true)],
        animation: .default
    )
    private var courts: FetchedResults<Courts>
    @FetchRequest(
        sortDescriptors: [NSSortDescriptor(keyPath: \Judges.name, ascending: true)],
        animation: .default
    )
    private var judges: FetchedResults<Judges>
    
    @State var courtSelected = 0
    @State var judgeSelected = 0
    
    var body: some View {
        if(courts.count > 0) {
            HStack{
                Picker(selection: $courtSelected, label: Text("Gericht")){
                    ForEach(0..<courts.count){ court in
                        Text("\(courts[court].name ?? "Unknown")").tag(court)
                    }
                }
            }
            HStack {
                Picker(selection: $judgeSelected, label: Text("Richter \(judgeSelected)")){
                    ForEach(Array(courts[courtSelected].courtsJudges as! Set<Judges>), id: \.self) { judge in
                        Text("\(judge.name ?? "")").tag(judge)
                    }
                }.id(UUID())
            }
            HStack {
                Button("neue Gerichte") {
                    addItem()
                    addJudges()
                }
            }
        }
    }
    
    private func addItem() {
        for id in 0..<3 {
            let newItem = Courts(context: viewContext)
            newItem.id = UUID()
            newItem.name = "Gericht Nr. \(id)"
            
            
            do {
                try viewContext.save()
            } catch {
                // Replace this implementation with code to handle the error appropriately.
                // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
                let nsError = error as NSError
                fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
            }
        }
        
    }
    
    
    private func addJudges() {
        for cd in 0..<courts.count {
            for jd  in 0..<3 {
                let newJudge = Judges(context: viewContext)
                newJudge.id = UUID()
                newJudge.name = "Richter \(jd) am Gericht \(courts[cd].name)"
                newJudge.judgesCourts = courts[cd]
                
                try? viewContext.save()
            }
        }
    }
    
}

The result: both pickers are shown, first ist ok, second shows the right judges, but they are not "selectable"

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文