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

时间:2020-10-17 21:37:56

标签: ios xcode swiftui

我有一个带有SwiftUI生命周期的SwiftUI应用程序,该应用程序使用TextFields和 TextEditors。我写了一个修饰符来处理滚动内容 存在键盘时,将其置于键盘下方。我的修改器按预期工作 对于TextFields,但对于TextEditor则完全没有。苹果文档说 keyboardWillShowNotification现为 在键盘显示之前立即张贴。我找不到任何东西 声明通知仅限于TextFields。两种字段类型都在同一个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 Beta(12B5018i)iOS 14

第一次编辑:我认为该问题很可能是TextEditor获得焦点时无法接收通知的原因。但是,将此修改器添加到TextEditor会显示该通知已触发。没有进展:

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

1 个答案:

答案 0 :(得分: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)
    }
}