关闭时如何将 UIToolBar 修复到键盘顶部

问题描述

我已经为键盘实现了滑动关闭,我希望 UITextField/UIToolBar 在键盘向下滑动的同时向下移动,所以基本上将 UIToolbar 固定到键盘的顶部。目前,UIToolbar 保持在其位置,直到键盘完全关闭..

enter image description here

解决方法

从一些代码开始会很好......但这是一个新项目,所有代码都在代码中完成,应该可以满足您的要求。

class ViewController: UIViewController {
    
    private var bottomConstraint: NSLayoutConstraint?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let bottomView = UIToolbar(frame: .init(x: 0.0,y: view.bounds.height-50.0,width: view.bounds.width,height: 50.0))
        bottomView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(bottomView)
        view.addConstraint(.init(item: bottomView,attribute: .left,relatedBy: .equal,toItem: view,multiplier: 1.0,constant: 0.0))
        view.addConstraint(.init(item: bottomView,attribute: .right,constant: 0.0))
        let bottomConstraint: NSLayoutConstraint = .init(item: bottomView,attribute: .bottom,constant: 0.0)
        view.addConstraint(bottomConstraint)
        view.addConstraint(.init(item: bottomView,attribute: .height,toItem: nil,attribute: .notAnAttribute,constant: 50.0))
        self.bottomConstraint = bottomConstraint
        
        let textField = UITextField(frame: .init(x: 0.0,y: 0.0,height: 50.0))
        textField.backgroundColor = .lightGray
        bottomView.items = [UIBarButtonItem(customView: textField)]
        
        view.addGestureRecognizer(UITapGestureRecognizer(target: textField,action: #selector(resignFirstResponder)))
        
        NotificationCenter.default.addObserver(self,selector: #selector(onKeyboardChange),name: UIResponder.keyboardWillChangeFrameNotification,object: nil)
    }
    
    @objc private func onKeyboardChange(notification: NSNotification) {
        guard let info = notification.userInfo else { return }
        guard let value: NSValue = info[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { return }
        
        let newFrame = value.cgRectValue
        
        let panel: UIView = self.view // Use whatever is the superview of constrained view
        let height = max(0,panel.bounds.height - panel.convert(newFrame.origin,from: nil).y)
        
        if let durationNumber = info[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber,let keyboardCurveNumber = info[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber {
            let duration = durationNumber.doubleValue
            let keyboardCurve = keyboardCurveNumber.intValue
            let curve: UIView.AnimationCurve = UIView.AnimationCurve(rawValue: keyboardCurve) ?? .linear
            let options = UIView.AnimationOptions(rawValue: UInt(curve.rawValue << 16))
            
            UIView.animate(withDuration: duration,delay: 0,options: options,animations: {
                self.bottomConstraint?.constant = -height
                panel.layoutIfNeeded()
            },completion: nil)

        } else {
            self.bottomConstraint?.constant = -height
            panel.layoutIfNeeded()
        }
    }

}

我会在故事板中做事情并使用出口...但这应该能让你更好地了解事情是如何设置的。