简体   繁体   中英

Set UIView at Keyboard height

I want to set my view bottom constrains equal to keyboard height. Keyboard is always active during lifecycle of VC.

However, when my VC is loading my view changing it's height in a strange way(as I showed in a gif)

In IB keyboardHeigthConstraint is constrains of Bottom Layout Guide Top and my View and equals to 0

 @IBOutlet weak var keyboardHeigthConstraint: NSLayoutConstraint!

   override func viewDidLoad() {
        super.viewDidLoad()
        cardNumberTextField.becomeFirstResponder()

        NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotification), name: NSNotification.Name.UIKeyboardWillChangeFrame , object: nil)
    }

func handleKeyboardNotification(notification: NSNotification) {

    if let userInfo = notification.userInfo {
        let keyboardFrame: CGRect = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue

        DispatchQueue.main.async {
            self.keyboardHeigthConstraint.constant = keyboardFrame.size.height
            self.view.layoutIfNeeded()
        }
    }

What could cause such strange behaviour?

在此处输入图片说明

There're a few problems in your code:

  • cardNumberTextField.becomeFirstResponder() should be called in viewWillAppear instead;
  • call cardNumberTextField.becomeFirstResponder() after you subscribe for keyboard notifications;
  • unsubscribe from keyboard notifications in viewDidDisappear ;
  • update the constraint without wraping it in DispatchQueue.main.async .

I think it should help.

@IBOutlet weak var keyboardHeigthConstraint: NSLayoutConstraint!

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotification), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
    cardNumberTextField.becomeFirstResponder()
}

override func viewDidDisappear(_ animated: Bool) {
    NotificationCenter.default.removeObserver(self)
    super.viewDidDisappear(animated)
}

func handleKeyboardNotification(notification: NSNotification) {
    guard let userInfo = notification.userInfo,
        let frameValue = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue else {

        return
    }

    let keyboardFrame = frameValue.cgRectValue
    keyboardHeigthConstraint.constant = keyboardFrame.height
    view.layoutIfNeeded()
}

You could also animate the height with

let keyboardDuration = (notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue

     UIView.animate(withDuration: keyboardDuration, animations: { 
        DispatchQueue.main.async {
           self.keyboardHeigthConstraint.constant = keyboardFrame.size.height
           self.view.layoutIfNeeded()
       }               
   })

From your gif image i can see your button is jumping and that may be the problem. Try adding button's vertical constraint with the textView and your button will always be in that position. If you want to support for all devices you have to calculate that vertical constraint according to device size.

actually all answers above hadn't provide the working solution for me, but my final variant is a collaboration of all of theese answres

I suppose, that the key problem was that I decided to change the bottom constrains. When I shifted to top one, "jumping" disappeared

 override func viewWillAppear(_ animated: Bool) {
        cardNumberTextField.becomeFirstResponder()
         NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardNotification), name: NSNotification.Name.UIKeyboardWillChangeFrame , object: nil)
    }

    override func viewDidDisappear(_ animated: Bool) {
        NotificationCenter.default.removeObserver(self)
        super.viewDidDisappear(animated)
    }


    func handleKeyboardNotification(notification: NSNotification) {

        guard let userInfo = notification.userInfo,
            let frameValue = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue
            else { return }

        let duration:TimeInterval = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSNumber)?.doubleValue ?? 0

        print(keyboardHeigthConstraint.constant)
        UIView.animate(withDuration: duration, animations: {
//hardcoded 116 - it is buttonHeight + navBarHeight
            self.keyboardHeigthConstraint.constant = UIScreen.main.bounds.height - frameValue.cgRectValue.size.height - 116
            self.view.layoutIfNeeded()
        })
         print(keyboardHeigthConstraint.constant)
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM