【问题标题】:SwiftUI TextEditor Scroll with Show Keyboard Not WorkingSwiftUI TextEditor 滚动显示键盘不起作用
【发布时间】:2021-02-01 01:33:29
【问题描述】:

我有一个带有 SwiftUI 生命周期的 SwiftUI 应用程序,它使用 TextFields 和 文本编辑器。我写了一个修饰符来处理滚动内容 当键盘存在时,位于键盘下方。我的修改器按预期工作 对于 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)
    }
}

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

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

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

【问题讨论】:

    标签: ios xcode swiftui


    【解决方案1】:

    我假设您应该将订阅者存储如下

    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)
        }
    }
    

    【讨论】:

    • 啊,是的。我相信这更好,但是它对性能没有影响。视图不滚动。我将编写一些代码来捕获通知。我能得出的唯一结论是,当 TextEditor 获得焦点时,keyboardWillShowNotification 没有被触发。
    • 运气好能解决这个问题吗?我在 Xcode 12.4/iOS 14.4.2 中遇到同样的问题?
    • iOS 15 / Xcode 13.1 也有同样的问题 有没有办法为 TextEditor 采用键盘?