Reputation:
I try now since a while to use data from a entity that be selected in a picker. But I feel in the moment like running again a wall and don't see the next step. So I hope I can get a tip from you which push me into the better way.
I have the following two entities, who be related with one-to-many (one manufacturer can have multiple type of devices)
In the application I list all types in a picker that it can be choosen for the calculation.
The code for the picker is
Picker("Select Type", selection: $selectedType) {
ForEach(0..<types.count, id: \.self) { index in
Text("\(types[index].wrappedName)")
.tag(index)
}
}
I can't get the origin indexkey for the row that I select in the picker. Is this the uuid? Also I can't add the manufacturer.name to the text in the picker.
Please give me a tip in which way I have to look.
Thanks a lot.
Here is the fully View
import SwiftUI
import CoreData
struct CalculateCopyView: View {
@Environment(\.managedObjectContext) private var viewContext
@FetchRequest(
sortDescriptors: [],
predicate: NSPredicate(format: "favorite == %@", true as NSNumber),
animation: .default)
var types: FetchedResults<TypeEntity>
@State private var selectedType: Int = 0
@State private var selectedBarString = "Top"
let barOptions: [String] = ["Top","Front"]
//This Data should be filled from database
@State private var winkel: Double = 15
@State private var laengeSchleifstueck: Double = 140
@State private var durchmesserSchleifrad: Double = 250.3
@State private var horizontal: Double = 50
@State private var vertikal: Double = 29
//***********************
let formatter: NumberFormatter = {
let formatter = NumberFormatter()
formatter.numberStyle = .decimal
return formatter
}()
func calculateBar(h: Double,v: Double) -> Double {
let t = h + v
return t
}
//This function should called always when one of the pickers would be
//changed and when the view would viewed for the first time with the
//first automatically selected value from the type-picker
func fetchDataforSelectedType (v: String) {
// v = value of the picker for the types (devices)
@FetchRequest(
sortDescriptors: [],
predicate: NSPredicate(format: "name == %@", v),
animation: .default
)
var types: FetchedResults<TypeEntity>
switch selectedBarString {
case "top":
horizontal = types[0].topHorizontal
vertikal = types[0].topVertical
case "front":
horizontal = types[0].frontHorizontal
vertikal = types[0].frontVertical
default:
print("no kind of bar is choosen")
}
}
var body: some View {
Form {
Section {
VStack {
Picker("Select Type", selection: $selectedType) {
ForEach(0..<types.count, id: \.self) { type in
Text("\(types[type].wrappedName)")
.tag(types[type])
}
}
}
}
Section {
VStack {
Picker(selection: $selectedBarString, label: Text("Select Bar")) {
ForEach(barOptions.indices, id: \.self) { index in
Text(barOptions[index])
.tag(barOptions[index])
}
}
.pickerStyle(SegmentedPickerStyle())
}
}
Section {
VStack {
HStack {
Text("Schleifrad")
TextField("Enter your score", value: $durchmesserSchleifrad, formatter: formatter)
.textFieldStyle(OutlinedTextFieldStyle(icon: Image(systemName: "pencil")))
}
}
.onTapGesture {
hideKeyboard()
}
VStack {
HStack {
Text("length tool")
TextField("Enter your score", value: $laengeSchleifstueck, formatter: formatter)
.textFieldStyle(OutlinedTextFieldStyle(icon: Image(systemName: "pencil")))
}
}
.onTapGesture {
hideKeyboard()
}
VStack {
Text("angle")
.frame(maxWidth: .infinity, alignment: .leading)
HStack {
Slider(value: $winkel , in: 7.0...32.0, step: 1.0)
Text(
String(format: "%.0f °", winkel)
)
}
}
.onTapGesture {
hideKeyboard()
}
}
.padding()
Section {
VStack {
HStack {
Text("Topbar: " )
.font(.title)
Text(String(format: "%.1f mm", calculateBar(h: horizontal, v: vertikal)))
.font(.title)
.frame(maxWidth: .infinity, alignment: .trailing)
}
}
.onTapGesture {
hideKeyboard()
}
}
}
}
}
Upvotes: 0
Views: 44
Reputation: 12125
Alternatively you could let the Picker pick a 'Type' directly. Just define selectedType
as type TypeEntity?
.
The manufacturer can be accessed directly from the type through the to-one relation: type.manufacturer
struct TypesView: View {
@FetchRequest(
sortDescriptors: [NSSortDescriptor(keyPath: \TypeEntity.name, ascending: true)],
animation: .default)
private var types: FetchedResults<TypeEntity>
@State private var selectedType: TypeEntity? = nil // directly pick an (optional) TypeEntity
var body: some View {
Form {
Picker("Select Type", selection: $selectedType) {
Text("keine Auswahl").tag(nil as TypeEntity?)
ForEach(types) { type in
Text(type.name ?? "?").tag(type as TypeEntity?)
}
}
if let type = selectedType {
let hersteller = type.manufacturer // access manufacturer through type to-one relation
Text("Hersteller: \(hersteller?.name ?? "?")")
}
}
.padding()
}
}
Upvotes: 1
Reputation: 285064
As selectedType
is Int
, the tag
must be Int
, too.
Renaming type
as index
makes it clearer
Picker("Select Type", selection: $selectedType) {
ForEach(0..<types.count, id: \.self) { index in
Text(types[index].wrappedName)
.tag(index)
}
}
And – unrelated – string interpolating a string is pointless
Upvotes: 1