如何让 SwiftUI 列表删除按钮工作? (或消失)

Posted

技术标签:

【中文标题】如何让 SwiftUI 列表删除按钮工作? (或消失)【英文标题】:How can I get SwiftUI List delete buttons to work? (or disappear) 【发布时间】:2021-10-29 01:59:14 【问题描述】:

我有一个允许删除和移动的列表。并且有一个与 List 关联的 EditButton :

struct IDLine: Identifiable, Codable   
  let id: Int
  let line: String
// IDLine


struct ContentView: View 
   ...
   @AppStorage("savedConversions") var conversions: [IDLine] = []
   ...

   var body: some View 
      ...
      List 
        ForEach(conversions)  Text($0.line)  // List of conversions
            .onDelete(perform: deleteConversion)
            .onMove(perform: moveConversion)
      
    ...

    
func deleteConversion(at offsets: IndexSet)  conversions.remove(atOffsets: offsets) 
func moveConversion(from source: IndexSet, to dest: Int)  conversions.move(fromOffsets: source, toOffset: dest) 

// ContentView
    

当我向左滑动列表的某一行时,该行的右边缘会出现一个红色矩形删除按钮。点击它什么都不做。如果我单击 EditButton,每一行都会在左侧得到一个圆形的“-”按钮,然后再次单击它什么也不做。 这并不全是坏事。如果在一行上向左滑动足够远,则调用 deleteConversion。当按下 EditButton 时,每行右侧会出现一个 3 行小把手,允许用户重新排序列表。

编辑:我添加了更多代码,希望它更易于解释。

【问题讨论】:

向我们展示一个完整的示例,它可以重现您的问题,包括deleteConversion conversions删除项目后,听起来视图没有更新,或者根本没有删除它。 为了诊断为什么删除按钮不起作用,我们至少需要查看您的deleteConversion 函数。关于让他们“消失”的问题 - 只需删除您的 onDelete 修饰符即可。 我认为这是 SwiftUI 中的一个错误。我的旧 UIKit 版本中的逻辑等效代码有效。出现的删除按钮应该只是调用 deleteConversion 函数的替代路径,但似乎只有其中一个被正确连接。 【参考方案1】:

我已经找出了问题所在。我在声明 List 的 VStack 上有一个 onTapGesture 修饰符。它用于隐藏键盘。当我删除该修饰符时,删除按钮再次开始工作。 这是一个有问题的最小应用程序:

import SwiftUI

struct IDLine: Identifiable, Codable   // To allow SwiftUI List to correctly edit with repeated strings
  let id: Int
  let value: String
// IDLine


struct ContentView: View 
    @State private var value: String = ""
    @State private var lines: [IDLine] = []
    @FocusState private var entryFocused: Bool

    var body: some View 
        VStack 
            Text("Enter value")
            TextField("value", text: $value).padding()
            .focused($entryFocused)
            HStack 
                Button("Add", action: addLine).disabled(value.count == 0)
                Button("Clear", action: clearLines).disabled(lines.count == 0)
                EditButton().disabled(lines.count == 0)
            .padding(20)
            List 
                ForEach(lines) 
                  Text($0.value)
                
               .onDelete(perform: deleteLine)
               .onMove(perform: moveLine)
            
        // VStack
        .onTapGesture  entryFocused = false 
    // body

    func nextLine() -> IDLine 
        let id = 1 + lines.reduce(0)  Swift.max($0, $1.id) 
        return IDLine(id: id, value: value)
    

    func addLine()  lines.append(nextLine()) 
    func clearLines()  lines = [] 
    func deleteLine(at offsets: IndexSet)  lines.remove(atOffsets: offsets) 
    func moveLine(from source: IndexSet, to dest: Int)  lines.move(fromOffsets: source, toOffset: dest) 


【讨论】:

以上是关于如何让 SwiftUI 列表删除按钮工作? (或消失)的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用swiftUI附带的幻灯片删除的情况下创建自定义删除按钮我没有使用列表,只是使用foreach循环

SwiftUI - 核心数据从按钮中删除项目

如何禁用 SwiftUI 的默认行为?

如何从 SwiftUI 列表和领域中删除数据

SwiftUI 核心数据

SwiftUI:如何让列表视图中的图像与列表项的操作不同?