取消向后滑动时,SwiftUI 应用程序冻结并占用 100% CPU

Bar*_*uik 7 crash xcode freeze ios swiftui

以下代码可能会使正在运行的应用程序在 iPhone(不是 iPad)或 iPhone 模拟器上无响应。Xcode 显示应用程序消耗 100% CPU,同时分配越来越多的内存。

struct SecondView: View {
    @State private var keyboardHeight: CGFloat = 0

    private let showPublisher = NotificationCenter.Publisher.init(
        center: .default,
        name: UIResponder.keyboardWillShowNotification
    ).map { (notification) -> CGFloat in
        if let rect = notification.userInfo?["UIKeyboardFrameEndUserInfoKey"] as? CGRect {
            return rect.size.height
        } else {
            return 0
        }
    }

    var body: some View {
        VStack(spacing: 20) {
            if keyboardHeight == 0 {
                Text("This is shown as long as there's no keyboard")
            }
            Text("This is the SecondView. Drag from the left edge to navigate back, but don't complete the gesture: crash results.")
        }.onReceive(self.showPublisher) { (height) in
            self.keyboardHeight = height
        }
        .navigationBarItems(trailing: Button("Dummy") {  })
    }
}

struct ContentView: View {
    @State var textInput = ""

    var body: some View {
        NavigationView {
            VStack(spacing: 20) {
                TextField("1. Tap here to show keyboard", text: self.$textInput)
                    .textFieldStyle(RoundedBorderTextFieldStyle())
                NavigationLink(destination: SecondView()) {
                    Text("2. Go to second screen")
                }
                Spacer()
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

要触发冻结:

  1. 点击文本字段使键盘出现
  2. 点击链接转到下一个屏幕
  3. 从屏幕左侧拖动,但不要完成该手势,而是提前释放

有一些解决方法:

  • 删除导航栏项目(虚拟按钮)SecondView
  • keyboardHeight删除变量的使用SecondView
  • ContentView导航前不要激活键盘

但是,我无法在我的应用程序中使用上述解决方法。有谁知道根本原因是什么?

Bar*_*uik -1

我可以在导航之前停用键盘,使用以下解决方法:

NavigationLink(destination: SecondView(), tag: 2, selection: $navigationSelection) {
    EmptyView()
}
Text("2. Go to second screen")
    .onTapGesture {
        UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
        self.navigationSelection = 2
    }

Run Code Online (Sandbox Code Playgroud)