因此,我有一个类,它具有一个名为keyboardHeight的已发布变量,用于检索keyboardHeight的值:
import UIKit
class KeyboardHeightHelper: ObservableObject {
@Published var keyboardHeight: CGFloat = 0
init() {
    self.listenForKeyboardNotifications()
}
private func listenForKeyboardNotifications() {
    NotificationCenter.default.addObserver(forName: UIResponder.keyboardDidShowNotification,
                                           object: nil,
                                           queue: .main) { (notification) in
                                            guard let userInfo = notification.userInfo,
                                                let keyboardRect = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return }
                                            
                                            self.keyboardHeight = keyboardRect.height
    }
    
    NotificationCenter.default.addObserver(forName: UIResponder.keyboardDidHideNotification,
                                           object: nil,
                                           queue: .main) { (notification) in
                                            self.keyboardHeight = 0
    }
}
}然后,在ContentView中,我只有一个TextField,当你开始/停止编辑字段时,它应该打印键盘高度:
import SwiftUI
struct ContentView: View {
    @State var textFieldText = ""
    @ObservedObject var keyboardHeightHelper = KeyboardHeightHelper()
    var body: some View {
    VStack {
        TextField("Text field",
                  text: $textFieldText, onEditingChanged: { _ in print("the keyboard height is \(self.keyboardHeightHelper.keyboardHeight)") })
        
    }
   }
}我遇到的问题是:当我没有编辑文本字段,然后单击它时,它会打印键盘高度为0.0 (我猜这是因为它在显示键盘之前获取了keyboardHeight值,所以此时高度是0.0,因为看不到键盘)。当我按return键时,键盘的高度(对于iPhone 8模拟器)打印为260.0的正确值。我的问题是,当我开始编辑时,如何访问键盘的值?
发布于 2020-07-26 23:58:53
尝尝这个。您可以只使用SwiftUI视图的一个修饰符来集成它:
extension UIResponder {
    static var currentFirstResponder: UIResponder? {
        _currentFirstResponder = nil
        UIApplication.shared.sendAction(#selector(UIResponder.findFirstResponder(_:)), to: nil, from: nil, for: nil)
        return _currentFirstResponder
    }
    private static weak var _currentFirstResponder: UIResponder?
    @objc private func findFirstResponder(_ sender: Any) {
        UIResponder._currentFirstResponder = self
    }
    
    var globalFrame: CGRect? {
        guard let view = self as? UIView else { return nil }
        return view.superview?.convert(view.frame, to: nil)
    }
}extension Publishers {
    static var keyboardHeight: AnyPublisher<CGFloat, Never> {
        let willShow = NotificationCenter.default.publisher(for: UIApplication.keyboardWillShowNotification)
            .map { $0.keyboardHeight }
        
        let willHide = NotificationCenter.default.publisher(for: UIApplication.keyboardWillHideNotification)
            .map { _ in CGFloat(0) }
        
        return MergeMany(willShow, willHide)
            .eraseToAnyPublisher()
    }
}
extension Notification {
    var keyboardHeight: CGFloat {
        return (userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect)?.height ?? 0
    }
}struct KeyboardAdaptive: ViewModifier {
    @State private var bottomPadding: CGFloat = 0
    func body(content: Content) -> some View {
        GeometryReader { geometry in
            content
                .padding(.bottom, self.bottomPadding)
                .onReceive(Publishers.keyboardHeight) { keyboardHeight in
                    let keyboardTop = geometry.frame(in: .global).height - keyboardHeight
                    let focusedTextInputBottom = UIResponder.currentFirstResponder?.globalFrame?.maxY ?? 0
                    self.bottomPadding = max(0, focusedTextInputBottom - keyboardTop - geometry.safeAreaInsets.bottom)
            }
            .animation(.easeOut(duration: 0.16))
        }
    }
}
extension View {
    func keyboardAdaptive() -> some View {
        ModifiedContent(content: self, modifier: KeyboardAdaptive())
    }
}用法:
struct ContentView: View {
    @State private var text = ""
    
    var body: some View {
        VStack {
            Spacer()
            
            TextField("Enter something", text: $text)
                .textFieldStyle(RoundedBorderTextFieldStyle())
        }
        .padding()
        .keyboardAdaptive()//note this
    }
}向多个在线来源致谢。
https://stackoverflow.com/questions/63102304
复制相似问题