SwiftUI响应drop操作弹出sheet不立即显示问题如何解决?
解决方案
根因分析
你遇到的问题本质是线程错误导致状态修改未触发视图即时刷新:NSItemProvider.loadItem的完成回调默认执行在后台全局队列,而SwiftUI要求所有对@State属性的修改必须在主线程执行,才能触发即时的视图重绘。你在后台线程修改sheetPresented后,系统不会主动触发视图刷新,只有等到下一次主线程的视图更新事件(比如再次拖拽元素)时,才会响应状态变化弹出Sheet。
另外你提供的代码里存在两处笔误:
@State定义的变量名是sheetPresented,但修改时写的是sheetIsPresented.sheet修饰符的参数名应为isPresented,不是你写的sheetPresented
修复方案
只需要把performDrop中修改状态的代码包装到主队列调度中即可,修改后的performDrop代码如下:
func performDrop(info: DropInfo) -> Bool { if let item = info.itemProviders(for: dropTypes).first { item.loadItem(forTypeIdentifier: UTType.utf8PlainText.identifier, options: nil) { (textData, error) in // 数据解析逻辑可保留在后台线程执行 guard let textData = textData as? Data, let droppedText = String(data: textData, encoding: .utf8), (你的判断条件) else { // 不满足条件的处理逻辑 return } // 所有修改@State的操作必须切到主线程执行 DispatchQueue.main.async { self.droppedText = droppedText self.sheetPresented = true // 修正变量名笔误 } } return true } return false }
同步修正.sheet修饰符的写法:
.sheet(isPresented: $sheetPresented, onDismiss: sheetReturn) { // 你的Sheet内容 }
内容的提问来源于stack exchange,提问作者Mussau
相关产品推荐
相关产品推荐

