ios - SwiftUI - 在工作表上显示工作表时间歇性崩溃
问题描述
当我在已经在工作表中的视图上显示工作表时,我发生了不可预测的崩溃。我已经能够慢慢地剥离我的视图和自定义类型的一部分,直到我得到下面仍然显示崩溃的非常简单和通用的视图结构。
当我与 TextField 交互然后与显示子表的按钮之一交互时,就会发生崩溃。有时需要在按钮和文本字段之间点击很多才能触发崩溃,有时它会立即发生(如下面的 GIF 所示)。有时我根本无法让崩溃发生,但我的用户不断报告它。
在下面的 gif 图中,崩溃发生在按下底部按钮的那一刻。您可以看到按钮永远不会退出其“按下”状态,并且工作表永远不会出现。
Xcode 没有提供任何有关崩溃的有用信息(截图如下)。
我只在运行 13.4.1 和 Xcode 11.4.1 的 iPhone XR 上实现了它。我已经在 iPhone 6s 和几个模拟器上尝试过,但无法触发崩溃,但用户已经在几个设备上报告了它。
struct ContentView: View {
@State var showingSheetOne: Bool = false
var body: some View {
Button(action: { self.showingSheetOne = true }) {
Text("Show")
}
.sheet(isPresented: $showingSheetOne) {
SheetOne(showingSheetOne: self.$showingSheetOne)
}
}
}
struct SheetOne: View {
@Binding var showingSheetOne: Bool
@State var text = ""
var body: some View {
VStack {
SheetTwoButton()
SheetTwoButton()
SheetTwoButton()
TextField("Text", text: self.$text)
}
}
}
struct SheetTwo: View {
@Binding var showing: Bool
var body: some View {
Button(action: {
self.showing = false
}) {
Text("Hide")
.frame(width: 300, height: 100)
.foregroundColor(.white)
.background(Color.blue)
}
}
}
struct SheetTwoButton: View {
@State private var showSheetTwo: Bool = false
var body: some View {
Button(action: { self.showSheetTwo = true } ) {
Image(systemName: "plus.circle.fill")
.font(.headline)
}.sheet(isPresented: self.$showSheetTwo) {
SheetTwo(showing: self.$showSheetTwo)
}
}
}
解决方案
几周前我遇到了类似的问题。事实证明,当我在打开键盘的情况下展示新工作表时,它会导致崩溃。
我发现UIApplication.shared.endEditing()
在显示第二张纸之前使用可以解决问题
更新
对于 iOS 14,我创建了一个扩展,因为上述功能不再可用
extension UIApplication {
static func endEditing() {
let resign = #selector(UIResponder.resignFirstResponder)
UIApplication.shared.sendAction(resign, to: nil, from: nil, for: nil)
}
}
用法类似UIApplication.endEditing()