Textview moving higher than expected on keyboardWillShowNotification for Iphone X

余生颓废 提交于 2020-03-05 03:56:14

问题


on a function I have titled handleKeyboardWillShow, my input textfield is moving higher than expected. It is my intention for the textfield to be pinned to the top of the keyboard view. I have also added the code to the creation of the text field that seems to be causing the issue.

Creation of the textField variable

  lazy var inputTextField: UITextField = {
    let tf = UITextField()
    tf.placeholder = "Enter message..."
    tf.translatesAutoresizingMaskIntoConstraints = false
    tf.delegate = self
    return tf
}()

My view did load function

    override func viewDidLoad() {
    super.viewDidLoad()
    collectionView.contentInset = UIEdgeInsets(top: 8, left: 0, bottom: 8, right: 0)
    collectionView.alwaysBounceVertical = true
    collectionView.register(ChatMessageCell.self, forCellWithReuseIdentifier: cellId)
    collectionView.backgroundColor = .white
    collectionView.keyboardDismissMode = .interactive
    becomeFirstResponder()
    setUpInputComponents()
    setUpKeyboardObserver()

}

View will disappear is where I remove the observers

 override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    //MARK: IMPORTANT FOR SHOWING AND HIDING KEYBOARD TO AVOID MEMORY LEAKS
    NotificationCenter.default.removeObserver(self)
}

func setUpKeyboardObserver(){
    NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)

    NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}

@objc func handleKeyboardWillShow(notification:NSNotification){
    let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect
            let keyboardDuration = (notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as AnyObject).doubleValue
    let safeLayoutGuideBot = UIApplication.shared.keyWindow?.safeAreaInsets.bottom
    let height =  (keyboardFrame?.height)! - safeLayoutGuideBot!
    containerViewBottomAnchor?.constant = -height
    UIView.animate(withDuration: keyboardDuration!, animations: {
        self.view.layoutIfNeeded()
    })
}

@objc func handleKeyboardWillHide(notification:NSNotification){
    let keyboardDuration = (notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as AnyObject).doubleValue
    containerViewBottomAnchor?.constant = 0
    UIView.animate(withDuration: keyboardDuration!, animations: {
        self.view.layoutIfNeeded()
    })
}

This is where the layout for the textView in question and container view are set up.

var containerViewBottomAnchor: NSLayoutConstraint?

func setUpInputComponents(){
    let containerView = UIView()
    containerView.translatesAutoresizingMaskIntoConstraints = false
    containerView.backgroundColor = .white
    view.addSubview(containerView)

    containerView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
    containerViewBottomAnchor =  containerView.bottomAnchor.constraint(equalTo: view.bottomAnchor)
    containerViewBottomAnchor?.isActive = true
    containerView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
    containerView.heightAnchor.constraint(equalToConstant: 50).isActive = true

    containerView.addSubview(sendButton)
    sendButton.rightAnchor.constraint(equalTo: containerView.rightAnchor).isActive = true
    sendButton.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
    sendButton.widthAnchor.constraint(equalToConstant: 80).isActive = true
    sendButton.heightAnchor.constraint(equalTo: containerView.heightAnchor).isActive = true

    containerView.addSubview(inputTextField)
    inputTextField.leftAnchor.constraint(equalToSystemSpacingAfter: containerView.leftAnchor, multiplier: 8).isActive = true
    inputTextField.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true
    inputTextField.rightAnchor.constraint(equalTo: sendButton.leftAnchor).isActive = true
    inputTextField.heightAnchor.constraint(equalTo: containerView.heightAnchor).isActive = true

    containerView.addSubview(seperatorLineView)
    seperatorLineView.leftAnchor.constraint(equalTo: containerView.leftAnchor).isActive = true
    seperatorLineView.topAnchor.constraint(equalTo: containerView.topAnchor).isActive = true
    seperatorLineView.widthAnchor.constraint(equalTo: containerView.widthAnchor).isActive = true
    seperatorLineView.heightAnchor.constraint(equalToConstant: 0.5).isActive = true
}

回答1:


It looks like you may be double counting the safe area. You should be able to just convert the keyboard's frame into your view's coordinate space and be done. Here's what my keyboard code looks like. Yours will be slightly different because you're using auto layout instead of frame based layout.

@objc func keyboardShown(_ notification: Notification) {
    let keyboardEndFrameWindow = (notification as NSNotification).userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue
    let keyboardTransitionDuration = (notification as NSNotification).userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as! NSNumber
    let keyboardTransitionAnimationCurve = (notification as NSNotification).userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as! NSNumber

    let keyboardEndFrameView = self.view.convert(keyboardEndFrameWindow.cgRectValue, from:nil)
    var offsetY = keyboardEndFrameView.minY - self.nameField.frame.maxY;
    offsetY = min(offsetY, 0);

    UIView.animate(withDuration: TimeInterval(keyboardTransitionDuration.doubleValue),
        delay: 0.0,
        options: UIView.AnimationOptions(rawValue: keyboardTransitionAnimationCurve.uintValue),
        animations: { () -> Void in
            self.view.frame = self.view.frame.offsetBy(dx: 0, dy: offsetY)
    }, completion: nil)
}



回答2:


Perhaps this fix was a hack, but I resolved it by implementing the following

        containerViewBottomAnchor?.constant -= (keyboardFrame?.height)! - 100

Statically subtracting the value of 100 from the keyboard frame height.



来源:https://stackoverflow.com/questions/60192971/textview-moving-higher-than-expected-on-keyboardwillshownotification-for-iphone

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!