简体   繁体   English

将UIView设置为键盘高度

[英]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. 键盘在VC的生命周期中始终处于活动状态。

However, when my VC is loading my view changing it's height in a strange way(as I showed in a gif) 但是,当我的VC加载视图时,以一种奇怪的方式更改其高度(如我在gif中所示)

In IB keyboardHeigthConstraint is constrains of Bottom Layout Guide Top and my View and equals to 0 在IB键盘中,HeigthConstraint是“底部布局向导顶部”和“我的视图”的约束,等于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; 应该在viewWillAppear调用cardNumberTextField.becomeFirstResponder()
  • call cardNumberTextField.becomeFirstResponder() after you subscribe for keyboard notifications; 订阅键盘通知后,调用cardNumberTextField.becomeFirstResponder()
  • unsubscribe from keyboard notifications in viewDidDisappear ; 取消订阅viewDidDisappear键盘通知;
  • update the constraint without wraping it in DispatchQueue.main.async . 更新约束而不将其包装在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. 从您的gif图像中,我可以看到您的按钮正在跳跃,这可能是问题所在。 Try adding button's vertical constraint with the textView and your button will always be in that position. 尝试在textView中添加按钮的垂直约束,然后您的按钮将始终处于该位置。 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)
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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