1

I noticed a surprising behavior: When I change the frame of a UIView after receiving the UIKeyboardWillShowNotification or UIKeyboardWillHideNotification, the change of the frame is animated. It seems like this animation uses the same duration and easing curve as the keyboard. In this project, I don't use Autolayout, I'm laying views out programmatically by setting their frames.

Can someone explain to me what is going on here?

Code

The interesting parts of the UIViewController's viewDidLoad():

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWillShow), name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(keyboardWillDisappear), name: UIKeyboardWillHideNotification, object: nil)

someView.frame = CGRect(origin: CGPoint(x: 0, y: view.bounds.height - 10), size: CGSize(width: 10, height: 10))
someView.backgroundColor = UIColor.redColor()
view.addSubview(someView)

The callbacks:

func keyboardWillShow(notification: NSNotification) {
    someView.frame.origin = CGPoint(x: 0, y: 0)
}

func keyboardWillDisappear(notification: NSNotification) {
    someView.frame.origin = CGPoint(x: 0, y: view.bounds.size.height - someView.bounds.size.height)    
}

Further details

  • The callbacks are called only once.
  • I'm using a standard UIViewController.
  • I'm not getting an animation in callbacks from the UIKeyboardDid... notifications
  • I can prevent the automatic animations by calling UIView.commitAnimations() before setting my UIViews Frame, but this seems hacky.
  • Autolayout shouldn't be involved, as I'm laying the views out by setting their frames

Further questions

  • Is this expected behavior?
  • Is it documented somewhere?
  • Is there a good way to disable animations like these?
  • Is it save to rely on this behavior?
  • Can I safely play custom animations when receiving a UIKeyboardWill... notification?
Jogga
  • 13
  • 1
  • 4

1 Answers1

1

The answers:

  • Yes, because the code inside those notifications are meant to be used exclusively to animate your view to respond to the keyboard's appearance, like to scroll scroll views, or move text fields to its correct place.
  • I couldn't find anything but the documentation of the keyboard notifications available here
  • Synchronizing Animations in keyboardWillShow keyboardWillHide -- Hardware Keyboard & Virtual Keyboard Simultaneously - related question
  • To disable these animations, call the didShow and didHide notifications, since they are meant to contain code to be executed after the animation have commited.
  • Yes.
  • As long as you work well with the keyboard animations, yes! But those notifications are meant to be used to deal with the keyboard animation interaction inside the view, and not other unrelated animations. You should those unrelated animation views you're trying to animate inside a scroll view and scroll it accordingly when receiving the keyboard notifications, to have a better experience.

Hope I helped.

Community
  • 1
  • 1
Roger Oba
  • 1,292
  • 14
  • 28
  • This definitely helps, thank you. As a follow up, do you consider this summary correct? [beginAnimations(_:context:)](https://developer.apple.com/reference/uikit/uiview/1622463-beginanimations) is called before sending `UIKeyBoardWill...` notifications. When I change a view's frame in the callback of one of these notifications, this happens inside of the begin/commit animation block. Hence these changes are animated. [commitAnimations()](https://developer.apple.com/reference/uikit/uiview/1622664-commitanimations) is ultimately called. – Jogga Sep 21 '16 at 16:44