Why are my SwipeActions overflowing the listview SwiftUI

59 Views Asked by At

Why is my SwiftUI Swipe Action behaving like this?

I don't now how to add a GIF in stack overflow so here is a imagur link https://i.stack.imgur.com/VCKEE.jpg. If you don't want to click on external links here is a image from the GIF:

This bug is only for the row 2, 3 and 4. Not for 1 and 5. If I add more items, the first and the last row wont have this bug

My View:

struct MyView: View {
@State var shops = [Shop.empty(), Shop.empty(), Shop.empty(), Shop.empty(), Shop.empty()]

var body: some View {
    NavigationView {
        List($shops) { $shop in
            Text(shop.name)
                .swipeActions {
                    Button {
                        shop.toggleFavourite()
                    } label: {
                        Image(systemName: "star")
                    }
                }
        }
    }
}
}

the shop struct:

struct Shop: Hashable, Identifiable {

var id: UUID

var favourite: Bool

init(id: UUID){
    self.id = id
    self.favourite = UserDefaults.standard.bool(forKey: id.uuidString)
}

mutating func toggleFavourite() {
    favourite.toggle()
    UserDefaults.standard.set(favourite, forKey: id.uuidString)
}

static func empty() -> Shop{
    Shop(id: UUID())
}
}

But I can't sadly I can't give you a working example, because I tried to run this code in a fresh app and it worked, without the Bug. On the same device. And I don't understand why, because I also put this view in the root of my old project, just for testing, and the bug stayed there.

I was able to figure out, that if I commented out this line:

UserDefaults.standard.set(favourite, forKey: id.uuidString)

my code would work. But unfortunately I can't just leave out this line of code. I tried several things, including wrapping this line into DispatchQueue.main.async {} and DispatchQueue.main.sync {}, same with the DispatchQueue.global(). I also added delays. Short delays wouldn't work at all (under .5 seconds) and longer delays would just delay the view bug. Of course I also tried wrapping this line into a separate function, and so on.

There are two mayor points, why I'am so confused:

  1. Why is the line, that sets this to the Userdefaults even influencing the view? I mean I checked with a print statement, that the initializer, which is the only section in my code that checks this Userdefaultvalue, only gets called when the view gets initialized.
  2. Why does the code work in a different project?

I know since I can't provide a working example of my bug it's hard for you to figure out whats wrong. If you have any ideas, I would be very happy!

0

There are 0 best solutions below