Strange UIView behavior when changing Y-start when the keyboard is visible

Context:

I have a UIView containing a UITextView. I want to move this UIView when the keyboard is visible. So the idea to change the Y position .

Problem:

Sometimes the UIView returns to its original position Y while the keyboard is still visible. And he doesn't come back anymore, even if I focus the input. I really don't know why.

Illustration (gif):

https://d17oy1vhnax1f7.cloudfront.net/items/2K0z3P1j1x2f0X2X1B2v/ci.gif

PS: The keyboard appears 3 times in Gif. It is a cycle, therefore it is difficult to distinguish the end.

the code

What I did, first I added a notification observer:

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

Then I defined a keyboard switch handler:

func keyboardWillChangeFrame(notification: NSNotification) {

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

    self.keyboardInfo["isVisible"] = self.view.frame.size.height - keyboardFrame.origin.y != 0
    self.keyboardInfo["height"] = keyboardFrame.size.height
    self.keyboardInfo["animationDuration"] = info[UIKeyboardAnimationDurationUserInfoKey] as! Double
    self.keyboardInfo["animationCurve"] = info[UIKeyboardAnimationCurveUserInfoKey] as! UInt

    if self.keyboardInfo["isVisible"] as! Bool {
        self.moveCommentInputUp()
    } else {
        self.moveCommentInputDown()
    }

}

After that, I defined methods that move up / down in the comment input view:

func moveCommentInputUp() {

    print("Moving up... ", self.commentFormView.frame.origin.y, " to ", self.view.frame.size.height - (self.keyboardInfo["height"] as! CGFloat) - self.commentFormView.frame.size.height)

    UIView.beginAnimations(nil, context: nil)
    UIView.setAnimationDuration(self.keyboardInfo["animationDuration"] as! TimeInterval)
    UIView.setAnimationCurve(UIViewAnimationCurve(rawValue: Int(self.keyboardInfo["animationCurve"] as! UInt))!)
    UIView.setAnimationBeginsFromCurrentState(true)

    ViewUtil.changeViewFrame(view: self.commentFormView, yPosition: self.view.frame.size.height - (self.keyboardInfo["height"] as! CGFloat) - self.commentFormView.frame.size.height)
    ViewUtil.removeShadowToView(self.commentFormLauncherButton)

    UIView.commitAnimations()

}

func moveCommentInputDown() {

    print("Moving down... ", self.commentFormView.frame.origin.y, " to ", self.view.frame.size.height)

    UIView.beginAnimations(nil, context: nil)
    UIView.setAnimationDuration(self.keyboardInfo["animationDuration"] as! TimeInterval)
    UIView.setAnimationCurve(UIViewAnimationCurve(rawValue: Int(self.keyboardInfo["animationCurve"] as! UInt))!)
    UIView.setAnimationBeginsFromCurrentState(true)

    ViewUtil.changeViewFrame(view: self.commentFormView, yPosition: self.view.frame.size.height)
    ViewUtil.addShadowToView(commentFormLauncherButton, position: CGSize(width: 0, height: 5))

    UIView.commitAnimations()

}

@IBAction func showCommentForm(_ sender: UIButton) {

    self.commentInput.becomeFirstResponder()

}

(. Gif) , 568 - - 568

// The numbers show the initial and the final value of the keyboard Y position

// Click on button to focus the input
Moving up...  568.0  to  282.0
// Tap anywhere
Moving down...  282.0  to  568.0

// Click again on button to focus the input
Moving up...  568.0  to  282.0
///// Write "hhh". The view is gone, I don't know why.
// Tap anywhere
Moving down...  568.0  to  568.0    // The view seems to move from 568 to 568, hugh

// Click on button to focus the input
Moving up...  568.0  to  282.0      // This didn't work apparently
// Tap anywhere
Moving down...  568.0  to  568.0    // 568 to 568 again

- ?

: iOS 9, Xcode 8, Swift 3

+4
2

, , CocoaPods.

textField, . , textField.

@IBOutlet weak var textFieldBottomConstraint: NSLayoutConstraint!

NSNotification.Name.UIKeyboardWillShow UIKeyboardWillHide viewDidLoad, UIKeyboardWillChangeFrame:

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

, textField:

func handleKeyboardNotification(notification: NSNotification) {
    if let userInfo = notification.userInfo {
        let keyboardFrameValue = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)
        let keyboardFrame = keyboardFrameValue?.cgRectValue

        let isKeyboardShowing = notification.name == NSNotification.Name.UIKeyboardWillShow

        textFieldBottomConstraint.constant = isKeyboardShowing ? keyboardFrame!.height + 4 : 4
        self.view.layoutIfNeeded()
    }
}

, textFieldBottomConstraint .

, textField , , , .

, !

YouTuber ! :

https://www.youtube.com/watch?v=p8IaS5lmhuM

+4

, , :

pod 'IQKeyboardManagerSwift'

IQKeyboardManagerSwift/Git

, , Framework AppDelegate, 100% . , . TextFields Views - . .

enter image description here

UIView , , InputAccessoryView.

    @IBOutlet weak var textField: UITextField!

override func viewDidLoad() {
    super.viewDidLoad()

    let customView = UIView(frame: CGRectMake(0, 0, 10, 100))
    customView.backgroundColor = UIColor.redColor()
    textField.inputAccessoryView = customView
}

, CHGInputAccessoryView

enter image description here

, .

+2

Source: https://habr.com/ru/post/1655252/


All Articles