SwiftUI:拖入空列表时崩溃

标签 swift swiftui-list swiftui

在 iOS 和 macOS 上的 Xcode 12.1 上的 SwiftUI 中,当将对象拖动到空列表时,[UITableViewRowData numberOfRowsInSection:] () 发生内部崩溃并且没有命令行输出。

即使我尝试使用列表中的 .onInsert(...) 处理掉落,它仍然会崩溃。 (永远不会调用 onInsert 闭包)

这是要重现的最小示例:

struct ContentView: View {
    let string = "Hello World"
    
    var body: some View {
        HStack {
            Text(string) // Object to drag
                .onDrag({NSItemProvider(object: string as NSString)})
            
            List {} // When dragging object onto here, there's a crash
        }
    }
}

我做错了什么?

最佳答案

是的,通过崩溃分析,它看起来像是 SwiftUI 缺陷,值得向 Apple 报告反馈。

这是处理这种情况的可能方法,它是安全的,并且即使/在 Apple 修复崩溃后也能继续工作。

使用 Xcode 12/iOS 14 测试(为演示添加列表边框)

demo

import SwiftUI
import UniformTypeIdentifiers

struct ContentView: View {
    let string = "Hello World"
    @State private var items: [String] = []

    // border with highlight added just for better visibility
    @State private var dragOver = false
    
    var body: some View {
        HStack {
            Text(string) // Object to drag
                .onDrag({NSItemProvider(object: string as NSString)})
            
            List {
                ForEach(items, id: \.self) {
                    Text($0)
                }
                .onInsert(of: [.text]) { index, providers in
                    self.handle(providers: providers, index: index)
                }
            }
            .overlay(helperOverlay()) // << helper to handle empty list
            .border(dragOver ? Color.red : Color.green, width: 4) // << just for demo
        }
    }
    
    private func helperOverlay() -> some View {
        Group {
            if items.isEmpty {
                Color.white.opacity(0.0001)  // << should be something opaque
                    .onDrop(of: [.text], isTargeted: $dragOver) { providers -> Bool in
                        self.handle(providers: providers)
                        return true
                    }
            }
        }
    }
    
    private func handle(providers: [NSItemProvider], index: Int? = nil) {
        guard let provider = providers.first else { return }
        provider.loadDataRepresentation(forTypeIdentifier: "public.text") { (data, _) in
            guard let data = data, let value = String(data: data, encoding: .utf8) else { return }
            if let index = index {
                items.insert(value, at: index)
            } else {
                items.append(value)
            }
        }
    }
}

关于SwiftUI:拖入空列表时崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64612021/

相关文章:

swift - SKScene 中的应用程序购买不起作用?

ios - 如何知道 SwiftUI 中的 SecureTextField 何时获得焦点或失去焦点?

swift - 如何为每个数组元素生成绑定(bind)

swift - 我无法在调试器中看到变量的值

ios - dequeueReusableCellWithIdentifier 快速加载需要时间

ios - Sinch 框架(Objective C)和 Swift 不兼容

ios - 无法在 SwiftUI 中使用 ForEach 和 CoreData 将数据正确传递给模态演示

swift - SwiftUI 列表的性能问题

xcode - SwiftUI - 嵌套列表

ios - SwiftUI:NavigationLink 内的水平 ScrollView 中断导航