Moving keyboard when editing multiple textfields w

2020-03-31 17:44发布

问题:

I have UIViewController which looks like this:

I set all the relevant constraints.

I'm trying to shift the UIView up when the keyboard shows up - when I click on the UITextfields below.

I have the following code:

static func addRemoveKeyboardObserver(addObserver: Bool, keyboardMargin: CGFloat, view: UIView?)
{
    Utils.keyboardMargin = keyboardMargin
    Utils.heightChangingView = view

    if addObserver
    {
        NotificationCenter.default.addObserver(self, selector: #selector(Utils.keyboardWillChange(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(Utils.keyboardWillChange(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(Utils.keyboardWillChange(notification:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
    }
    else
    {
        NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
        NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
        NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillChangeFrameNotification, object: nil)

        Utils.keyboardHeight = 0
    }
}

@objc static func keyboardWillChange(notification: Notification)
{
    let userInfo = notification.userInfo!
    let beginFrameValue = (userInfo[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)!
    let beginFrame = beginFrameValue.cgRectValue

    let viewShouldMove = notification.name == UIResponder.keyboardWillShowNotification || notification.name == UIResponder.keyboardWillChangeFrameNotification 

    if Utils.keyboardHeight == 0 { Utils.keyboardHeight = -beginFrame.height + Utils.keyboardMargin }

    let duration:TimeInterval = (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0
    let animationCurveRawNSN = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber
    let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIView.AnimationOptions.curveEaseInOut.rawValue
    let animationCurve:UIView.AnimationOptions = UIView.AnimationOptions(rawValue: animationCurveRaw)

    if let view = Utils.heightChangingView
    {
        view.frame.origin.y = viewShouldMove ? Utils.keyboardHeight : 0
        UIView.animate(withDuration: duration, delay: TimeInterval(0), options: animationCurve,                                               animations: { view.layoutIfNeeded() }, completion: nil)
    }
}

The issue I'm facing is -

But then, when I click the second one, it shifts again, and now it looks like this:

I noticed that if I remove the constraints, the issue goes away, however, I do need to use the constraints.

So, what am I missing here?

回答1:

You must use scrollview for your uiview controller and then you can use notification for adjusting your uiview constraint.

Your UIViewController hierarchy should be like this

ContainerView --> ScrollView --> Content View --> Now Your View.

I'm suggesting you to use pod 'TPKeyboardAvoiding' for future animations in scrollview since for every controller you don't want to put notifications to shifting your UIView.

Here is link demo for your UIView shifting https://github.com/Vasu05/ScrollViewExample