UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Initializing an Edit Form

Forums > SwiftUI

@sweih  

Hi,

since I managed with your help to pass correct viewModel and data to my EditForm, I still cannot edit Ints or using a picker. There is the code

struct FoodDetailView: View {

    @Environment(\.presentationMode) var presentationMode
    @StateObject var food: Food
    let viewModel:FoodViewModel  

    @State private var amount:Int16 = 0
    @State private var name:String = ""
    @State private var amountUnit:String = ""

    init(food:Food, viewModel:FoodViewModel) {
        self._food = StateObject(wrappedValue:food)
        self.viewModel = viewModel
        self._amount = State(initialValue:food.amount)
        self._amountUnit = State(initialValue: food.amountunit ?? "g")
        self._name = State(initialValue: food.name ?? "")
        print ("Init \(name) \(amount)  \(amountUnit) ")

    }

    var body: some View {
        NavigationView {
            Form {
                Section(header:Text("Name des Lebensmittels")) {
                    TextField(food.name ?? "Lebensmittel", text:$name)
                }

                Section(header:Text("Portionsgröße")) {

                    TextField(String(food.amount), value: $amount, formatter: NumberFormatter())

                    Picker("Einheit", selection:$amountUnit) {
                        Text("g").tag("g")
                        Text("ml").tag("ml")
                    }.pickerStyle(SegmentedPickerStyle())

                }

                Button("Save") {
                    viewModel.updataFood(entity: food, name: name, amountUnit: food.amountunit ?? "g", amount: Int16(amount))
                    self.presentationMode.wrappedValue.dismiss()
                }
            }.navigationTitle("Detail")
        }
    }
}

I tried to use my own init-function to set values. This works as far as I can see. Editing the food.name works fine, but editing food.amount(Int) or food.amountunit (based on a Picker) does not work. I stepped into Save-Action in the Debugger -> There are still the values I set within init set.

2      

Not sure but in you have food.amountunit ?? "g" when think you should have the new value of amountUnit

viewModel.updataFood(entity: food, name: name, amountUnit: amountunit, amount: Int16(amount))

Also try to have the amount: Int16 to be just amount: Int then when you update cast it to Int16

It just a thought as the food name updates

2      

@sweih  

Thanks. The enum binding is now working properly, but binding an Int still does not work. I try it like this....

import SwiftUI

struct AddFoodView: View {

    @Environment(\.presentationMode) var presentationMode 
    @State private var name:String = ""
    @State private var amountUnit:AmountUnit = .g
    @State private var amount:Int = 50

    var viewModel:FoodViewModel

    var body: some View {
        NavigationView {
            Form {

                Section(header:Text("Name des Lebensmittels")) {
                    TextField("Name", text:$name)
                }
                Section(header:Text("Portionsgröße")) {

                    TextField("Menge", value: $amount, formatter: NumberFormatter()).keyboardType(.numberPad)
                    Text("Resulting \(amount)") // Even this text is not updated!!

                    Picker("Einheit", selection:$amountUnit) {
                        Text("g").tag(AmountUnit.g)
                        Text("ml").tag(AmountUnit.ml)
                    }.pickerStyle(SegmentedPickerStyle())
                }

                Button("Save") {
                    viewModel.addFood(name: self.name, amountUnit: self.amountUnit, amount: self.amount)
                    self.presentationMode.wrappedValue.dismiss()
                }
            }.navigationTitle("Detail")
        }
    }
}

Even the textfield which outputs "Resulting (amount)" is never updated. The field is initialized correctly with 50. But when you enter other numbers nothing, really nothing changes.

2      

@sweih  

I found a workaround now and therefore created a new Controll named IntField:

import Foundation
import SwiftUI
import Combine

struct IntField: View {
    let text:String
    @Binding var int: Int
    @State private var intString: String  = ""
    var body: some View {
        return TextField(text, text: $intString)
            .keyboardType(.numberPad)
            .onReceive(Just(intString)) { value in
            if let i = Int(value) { int = i }
            else { intString = "\(int)" }
        }
        .onAppear(perform: {
            intString = "\(int)"
        })
    }
}

Usage of IntField:

IntField(text:"Amount", int:value)

But I still do not understand, why working with value and formatter does not work at all.

2      

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.