Home > other >  Function don't get executed correctly - Swift
Function don't get executed correctly - Swift

Time:11-20

I've written some code but its not working as expected. I have the following code: My Contend View File:

import SwiftUI

struct ContentView: View {
    @State var liste: [Can] = [Can()]
    var body: some View {
        Button {
            liste[0].nested.change()
        } label: {
            Text("\(liste[0].nested.property)")
        }
    }
}

and an other file:

import SwiftUI

struct Can: Identifiable, Equatable, Codable, Hashable {
    
    static func == (lhs: Can, rhs: Can) -> Bool {
        lhs.id == rhs.id
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
    
    // Jedes Item
    let id = UUID()
    
    var nested = nestedThingies()
    
    struct nestedThingies: Codable {
        var property = 15
        mutating func change(){
            property -= 1
        }
    }
}

What I would expect from this code is that each time you press the button in ContentView, the value of the nested.property of the first item in the Array liste gets 1 lower (property -= 1).

What's Really Happening: The function change() gets called, but the value of property only changes from 15 to 14 no Mather how often you press that button.

I've tested that code also in a empty Project, and it did the same strange thing...

Can someone explain that behavior to me? Thanks, Boothosh

CodePudding user response:

The issue is your implementation of Equatable. You're telling the system that the elements are equal if their id properties match. But, that's not true -- they are distinctly different if their nested values change.

SwiftUI is taking your word for the fact that the elements are the same and doesn't update the UI. I'm not sure why it gets the first update right, but it definitely doesn't get the subsequent ones right. To make matters even more strange, if you print the property value after it changes, it prints down to 13, even though the UI stops updating at 14. My theory is that the erroneous Equatable function (==) is interfering with the @State storage that the system is doing.

If you update your == function to reflect the changed nested value, it works as expected:

struct Can: Identifiable, Equatable, Codable, Hashable {
    
    static func == (lhs: Can, rhs: Can) -> Bool {
        lhs.id == rhs.id && lhs.nested.property == rhs.nested.property
    }
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
    
    // Jedes Item
    var id = UUID()
    
    var nested = nestedThingies()
    
    struct nestedThingies: Codable {
        var property = 15
        mutating func change(){
            property -= 1
        }
    }
}
  • Related