【问题标题】:How to implement delete and move function using SwiftUI framework如何使用 SwiftUI 框架实现删除和移动功能
【发布时间】:2019-06-07 06:55:28
【问题描述】:

无法为列表视图中的项目删除和移动行。

Apple 在他们的培训视频中提供了这些方法,但它不起作用

删除:

array.remove(atOffsets: IndexSet)

搬家:

array.move(fromOffsets: IndexSet, toOffset: Int)

苹果文档中没有这两种方法。

【问题讨论】:

    标签: swiftui


    【解决方案1】:

    这些方法是 Swift 5.1 标准库的一部分,Apple 将在未来的 Xcode 测试版中提供该标准库。同时,您可以使用这些扩展:

    extension Array {
        mutating func remove(atOffsets offsets: IndexSet) {
            let suffixStart = halfStablePartition { index, _ in
                return offsets.contains(index)
            }
            removeSubrange(suffixStart...)
        }
    
        mutating func move(fromOffsets source: IndexSet, toOffset destination: Int) {
            let suffixStart = halfStablePartition { index, _ in
                return source.contains(index)
            }
            let suffix = self[suffixStart...]
            removeSubrange(suffixStart...)
            insert(contentsOf: suffix, at: destination)
        }
    
        mutating func halfStablePartition(isSuffixElement predicate: (Index, Element) -> Bool) -> Index {
            guard var i = firstIndex(where: predicate) else {
                return endIndex
            }
    
            var j = index(after: i)
            while j != endIndex {
                if !predicate(j, self[j]) {
                    swapAt(i, j)
                    formIndex(after: &i)
                }
                formIndex(after: &j)
            }
            return i
        }
    
        func firstIndex(where predicate: (Index, Element) -> Bool) -> Index? {
            for (index, element) in self.enumerated() {
                if predicate(index, element) {
                    return index
                }
            }
            return nil
        }
    }
    

    【讨论】:

      【解决方案2】:

      他们要么使用了 Array 的自定义扩展,要么使用了一些尚未公开的 Swift 版本。我实施的解决方法是:

      删除

      
      func delete(at offsets: IndexSet) {
          if let first = offsets.first {
              store.rooms.remove(at: first)
          }
      }
      

      移动

      
      func move(from source: IndexSet, to destination: Int) {
          if let first = source.first {
              store.rooms.swapAt(first, destination)
          }
      }
      

      移动功能有效,但动画效果不如 WWDC 2019 上的视频。

      【讨论】:

        【解决方案3】:

        您所指的方法现在可以在 Xcode 11 GM 上使用。你可以像这样使用它们。

        移除元素

        TLDR:

        .onDelete{offsets in
                    self.array.remove(atOffsets: offsets)
        

        完整代码(可复制粘贴): 导入 SwiftUI

        struct MyTableView : View {
        
        @State var array=[1,2,3,4,5]
        
        var body: some View {
        
            List{
                ForEach(array,id:\.self){element in
                    Text("\(element)")
                }
                .onDelete{offsets in
                    self.array.remove(atOffsets: offsets)
        
                }
            }
        
            }
        }
        
        
        struct MyTableView_Previews : PreviewProvider {
            static var previews: some View {
                MyTableView()
            }
        }
        

        移动元素

        .onMove { (offsets, targetOffset) in
                    self.array.move(fromOffsets: offsets, toOffset: targetOffset)
                }
        

        【讨论】:

        • 感谢您的解决方案...但我一直在寻找与使用 indexSet 使用方法 array.remove(atOffsets: IndexSet) 在索引处删除相关的 API,以及用于移动:array.move(fromOffsets: IndexSet, toOffset: Int)。这些方法是在 WWDC 2019 Intro to SwiftUI 中介绍的。我在最新版本的 xcode 11 中找不到。顺便说一句,将项目从一个索引移动到另一个索引的任何解决方法。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-18
        相关资源
        最近更新 更多