SwiftUI - 使用上下文菜单删除列表中的行 - 用户界面故障

18

我有一个使用List在我的SwiftUI View中展示的项目数组。我试图添加一个contextMenu来删除List中的单个项目。以下是结果。

delteing items from list

动画效果不如预期。每一行在移动到下一行前都会闪烁。如何设置animation.right或类似的东西,以便没有UI故障,并且看起来像onDelete发生的默认行为。

PS:我不能使用onDelete,因为在我的应用程序中,向右和向左滑动具有其他功能。

这是代码。


struct ListDelete: View {
    
    @State var cars = ["Tesla", "Mercedes", "Audi", "Tata", "Jaguar"]
    
    var body: some View {
        List(cars, id: \.self) { car in
            Text(car).contextMenu {
                Button(action: {
                    if let index = self.cars.firstIndex(of: car) {
//                        self.cars.remove(at: index)
                        self.cars.remove(atOffsets: [index])
                    }
                }, label: {
                    HStack {
                        Text("Delete")
                        Spacer()
                        Image(systemName: "trash")
                    }
                })
            }
        }
    }
}

使用的两种方法从数组中移除元素,导致了相同的行为。


1
这是一个有趣的问题。如果没有人回答,考虑设置悬赏吧。我实际上已经尝试寻找解决方案,但是没有找到。 - Glenn Posadas
3个回答

18

这是一个关于SwiftUI的问题,希望苹果会在下一个重大发布版本中修复它。 目前,您可以通过在上下文按钮操作之前添加小延迟来解决该问题:

DispatchQueue.main.asyncAfter(deadline: .now() + 0.7){
    //delete row
}

这是一种非常丑陋的修复方式,但我找不到其他替代方案。 - Alec von Barnekow

3

它来自List,不幸的是,ListStyle协议没有任何公共API。我现在看到的唯一方法是使用ScrollView模拟List。

import SwiftUI

struct ContentView: View {

    @State var cars = ["Tesla", "Mercedes", "Audi", "Tata", "Jaguar"]
    var body: some View {
        ScrollView {
            ForEach(cars, id: \.self) { car in
                VStack(alignment: .leading, spacing: 0) {
                    HStack {
                        Text(car).padding()
                        Spacer()
                    }
                    .contextMenu {
                        Button(action: {
                            if let index = self.cars.firstIndex(of: car) {
                                    self.cars.remove(at: index)
                            }
                        }, label: {
                            HStack {
                                Text("Delete")
                                Spacer()
                                Image(systemName: "trash")
                            }
                        })
                    }
                    Divider().padding(.leading)
                }.padding(.bottom, 0) // set -4 to be symetric
            }
        }
    }
}

with the following result

enter image description here


你的回答符合我提出的问题。但是在我正在构建的真实应用程序的要求中,我们有一个部分标题和一个随着滚动从大到内联的标题。当我使用ScrollView而不是带有标题的List时,标题也会随着ForEach一起滚动,这不是期望的行为。如果我使用VStack并将标题和ScrollView放在其中,则当我们滚动时标题保持不变。有没有办法同时实现两者? - imthath
你的“list”是表单的一部分吗? - user3441734
@Imthath,你最好再问一下,提供一个简化的代码片段来反映你的需求。(我几秒钟前刚读到关于节标题的内容 :-)) - user3441734
不,我的列表不是表单的一部分。我会发布一个单独的问题。 - imthath
@Imthath请告诉我(在此处放置链接) - user3441734

-1

这是一个与 contextMenu 相关的问题,闪烁是上面列表项的白色背景影响了 contextMenu。因此,你可以通过自己创建 contextMenu 来解决这个问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接