Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
325 views
in Technique[技术] by (71.8m points)

swift - How to get rid of a glitch when deleting a ForEach item

I have a MyObservableObject showing [ForEachItem] and a ForEachShowTest view.

When I want to "delete" an item from visibility, I want to do it via contextMenu and setting show = false. The issue is, there is a glitch with items overlay for a second. I managed to deal with it via using DispatchQueue but now it feels less responsive as it takes time for the item to disappear. Is there any other way?

You can try it yourselves or see a video: we.tl/t-5jMLsTD2dW

view:

struct ForEachShowTest: View {
    @ObservedObject var myObservableObject = MyObservableObject()
    var forEachList: [ForEachItem] { myObservableObject.forEachList.filter({ $0.show }) }
    var body: some View {
        VStack {
            ForEach(forEachList) { item in
                HStack {
                    Text(item.item)
                    
                }
                .contextMenu {
                    Button("Don't show without glitch") {
                        item.show = false
                        DispatchQueue.main.asyncAfter(deadline: .now() + .milliseconds(800)) {
                            myObservableObject.updateUI = true
                        }
                    }
                    Button("Don't show with glitch") {
                        item.show = false
                        myObservableObject.updateUI = true
                    }
                }
                
            }
            Spacer()
        }
    }
}

ObservableObject:

class MyObservableObject: ObservableObject {
    var forEachList: [ForEachItem] = [ ForEachItem(item: "I love ForEach"), ForEachItem(item: "Another list"), ForEachItem(item: "I want to show this one"), ForEachItem(item: "I want to show this one"), ForEachItem(item: "I want to show this one") ]
    @Published var updateUI: Bool = false
    
    init() { }
}

class ForEachItem: Identifiable {
    let id: UUID
    let item: String
    var show: Bool
    
    init(item: String, show: Bool = true) {
        id = UUID()
        self.item = item
        self.show = show
    }
}
question from:https://stackoverflow.com/questions/65832847/how-to-get-rid-of-a-glitch-when-deleting-a-foreach-item

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

It seems to be a issue with Swift UI. You get the same behavior with lists too: SwiftUI - delete row in list with context menu - UI glitch

If working with a List is an option for you, you may use the .onDelete() modifier for hiding the item without deleting it as a workaround:

    List {
        ForEach(forEachList) { item in
            HStack {
                Text(item.item)
                
            }
        }.onDelete(perform: { indexSet in
            for index in indexSet{
                forEachList[index].show = false
            }
            myObservableObject.updateUI = true
        })
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...