0

I am fairly new to iOS development. I am trying to update the property "cars" in the "Sire" model using a stepper. Whenever I press on + or - from the stepper controls, it changes the value by a step and then becomes disabled.

If I bind the stepper to the variable cars, it works flawlessly.

struct AddSireView: View {
//    @EnvironmentObject var sireVM:SiresViewModel
    @State var newSire = Sire (id:"", name: "", ownerID: 0, info:"", achievments: "", cars: 0, cups: 0)
    @State var cars = 0
    @State var cups = 0
    @State private var state = FormState.idle
    
    var createAction: CreateAction
    
    // TODO: Put validation that the added sire is valid and if not show errors to the user

    var body: some View {

            Form {
                VStack (spacing: 18) {
                    TitledTextView(text: $newSire.name, placeHolder: "الاسم", title: "الاسم")
                    
                    TiltedTextEditor(text: Binding<String>($newSire.info)!, title: "معلومات البعير")
                    TiltedTextEditor(text: Binding<String>($newSire.achievments)!, title: "انجازات البعير")
                }
                
                Stepper(value: $newSire.cars, in: 0...10,step:1) {
                    HStack {
                        Text ("سيارات:")
                        TextField("Cars", value: $newSire.cars, formatter: NumberFormatter.decimal)
                    }
                }

enter image description here

And this is the "Sire" struct

struct Sire: Hashable, Identifiable, Decodable  {
    static func == (lhs: Sire, rhs: Sire) -> Bool {
        lhs.id == rhs.id && lhs.name == rhs.name && lhs.ownerID == rhs.ownerID
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
        hasher.combine(name)
        hasher.combine(ownerID)

    }
     var id:String
     var name:String
     var ownerID:Int
     var fatherID:String?
     var info:String?
     var achievments:String?
     var cars:Int = 0
     var cups:Int = 0
    
     
    init (id:String, name:String, ownerID:Int, info:String? = nil, achievments:String? = nil,
          fatherID:String? = nil, cars:Int = 0, cups:Int = 0) {
         self.id = id
         self.name = name
         self.ownerID = ownerID
         self.cars = cars
         self.cups = cups
        self.info = info
        self.achievments = achievments
     }  
     
}

"Sire" was a class and i made it a Struct thinking that that was the problem, but to no avail.

2
  • 1
    Get rid of the custom implementations for Equatable and Washable you don't include cars in it so SwiftUI doesn't know when to reload. Commented Nov 4, 2022 at 11:48
  • @loremipsum This solved the problem. Now it is working. Thanks so much.Could you refer to me to relevant documentation or explain it to me? Could you put it as an answer to check it as correct? Commented Nov 4, 2022 at 13:36

2 Answers 2

3

Consider this approach using an ObservableObject to hold your Sire. This allows you to use both the Stepper and the Textfield at the same time.

 struct ContentView: View {
     @StateObject var sireModel = SireModel() // <-- here
     
     var body: some View {
         Form {
             Stepper(value: $sireModel.sire.cars, in: 0...10, step:1) {
                 HStack {
                     Text ("سيارات: ")
                     TextField("", value: $sireModel.sire.cars, formatter: NumberFormatter())
                 }
             }
         }
     }
 }

 class SireModel: ObservableObject {
     @Published var sire: Sire = Sire(id:"", name: "", ownerID: 0, info:"", achievments: "", cars: 0, cups: 0)
 }
Sign up to request clarification or add additional context in comments.

1 Comment

This doesn't address the cause of the issue it is just a workaround.
1

Get rid of the custom implementations for Equatable and Hashable (func == and func hash) you don't include cars in it so SwiftUI doesn't know when to reload.

SwiftUI is all about identity if you change how Swift computes the identity (using Hashable, Equatable and Identifiable) you change the behavior.

Check out Demystify SwiftUI

The video above is the "best" place to learn about the concept.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.