SwiftUI TextEditor 滚动显示键盘不起作用

use*_*617 5 xcode ios swiftui

我有一个具有 SwiftUI 生命周期的 SwiftUI 应用程序,它使用 TextFields 和 TextEditors。我编写了一个修饰符来处理当键盘存在时滚动键盘下方的内容。我的修改器对于文本字段按预期工作,但对于文本编辑器根本不起作用。苹果文档称,keyboardWillShowNotification 是在键盘显示之前立即发布的。我找不到任何说明通知仅限于文本字段的内容。两种字段类型都在同一个 ScrollView 中。希望我在这里遗漏了一些简单的东西。

我的修改器:

struct AdaptsToSoftwareKeyboard: ViewModifier {

    @State var currentHeight: CGFloat = 0

    func body(content: Content) -> some View {
        content
            .padding(.bottom, self.currentHeight)
            .edgesIgnoringSafeArea(self.currentHeight == 0 ? Edge.Set() : .bottom)
            .onAppear(perform: subscribeToKeyboardEvents)
    }

    private let keyboardWillOpen = NotificationCenter.default
        .publisher(for: UIResponder.keyboardWillShowNotification)
        .map { $0.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as! CGRect }
        .map { $0.height }

    private let keyboardWillHide =  NotificationCenter.default
        .publisher(for: UIResponder.keyboardWillHideNotification)
        .map { _ in CGFloat.zero }

    private func subscribeToKeyboardEvents() {
        _ = Publishers.Merge(keyboardWillOpen, keyboardWillHide)
            .subscribe(on: RunLoop.main)
            .assign(to: \.self.currentHeight, on: self)
    }
}
Run Code Online (Sandbox Code Playgroud)

任何指导将不胜感激。Xcode 版本 12.2 测试版 (12B5018i) iOS 14

第一次编辑:我认为问题可能是当文本编辑器接收焦点时无法接收通知。但是,将此修饰符添加到文本编辑器会显示通知已被触发。没有进展:

   .onReceive(NotificationCenter.default.publisher(for: UIApplication.keyboardWillShowNotification)) { _ in
        print("Cursor is in TextEditor!")
    }
Run Code Online (Sandbox Code Playgroud)

Asp*_*eri 3

我假设你应该按如下方式存储订阅者

struct AdaptsToSoftwareKeyboard: ViewModifier {

    @State var currentHeight: CGFloat = 0
    @State private var cancelable: AnyCancellable?
    
    func body(content: Content) -> some View {
        content
            .padding(.bottom, self.currentHeight)
            .edgesIgnoringSafeArea(self.currentHeight == 0 ? Edge.Set() : .bottom)
            .onAppear(perform: subscribeToKeyboardEvents)
    }

    private let keyboardWillOpen = NotificationCenter.default
        .publisher(for: UIResponder.keyboardWillShowNotification)
        .map { $0.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as! CGRect }
        .map { $0.height }

    private let keyboardWillHide =  NotificationCenter.default
        .publisher(for: UIResponder.keyboardWillHideNotification)
        .map { _ in CGFloat.zero }

    private func subscribeToKeyboardEvents() {
        self.cancelable = Publishers.Merge(keyboardWillOpen, keyboardWillHide)
            .subscribe(on: RunLoop.main)
            .assign(to: \.self.currentHeight, on: self)
    }
}
Run Code Online (Sandbox Code Playgroud)