SwiftUI-在工作表上显示工作表时间歇性崩溃

时间:2020-05-04 18:36:39

标签: ios swift 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)
        }
    }

}

Crash screen recording Xcode Crash 01 Xcode Crash 02 Xcode Crash 03 Xcode Crash 04

1 个答案:

答案 0 :(得分:2)

几周前,我遇到了类似的问题。原来,当我在打开键盘的情况下呈现新工作表时,会导致崩溃。

在显示第二张纸之前,我发现使用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()