aotian16
aotian16

Reputation: 819

swift animation not work in UIKeyboardWillShowNotification event

I don't know why animation work fine in UIKeyboardDidShowNotification event but not work in UIKeyboardWillShowNotification event.

Code looks like this:

anim in the comment code not work good, color will change but duration = 4 is not right

import UIKit
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name:UIKeyboardWillShowNotification, object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name:UIKeyboardWillHideNotification, object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardDidShow:"), name:UIKeyboardDidShowNotification, object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardDidHide:"), name:UIKeyboardDidHideNotification, object: nil)
    }
    deinit {NSNotificationCenter.defaultCenter().removeObserver(self)}
    func keyboardDidShow(notification: NSNotification) {
        showAnima1()
    }
    func keyboardDidHide(notification: NSNotification) {
        showAnima2()
    }
    func keyboardWillShow(notification: NSNotification) {
//        showAnima1() // animate not work here
    }
    func keyboardWillHide(notification: NSNotification) {
//        showAnima2() // animate not work here
    }
    func showAnima1() {
        UIView.animateWithDuration(4, delay: 0, options: UIViewAnimationOptions(rawValue: 7), animations: { () -> Void in
            self.view.backgroundColor = UIColor.greenColor()
            }) { (finish) -> Void in
                print("animate state = \(finish)")
        }
    }
    func showAnima2() {
        UIView.animateWithDuration(4, delay: 0, options: UIViewAnimationOptions(rawValue: 7), animations: { () -> Void in
            self.view.backgroundColor = UIColor.whiteColor()
            }) { (finish) -> Void in
                print("animate state = \(finish)")
        }
    }
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {self.view.endEditing(false)}
}

Sorry, i see comment in source code says:

// Each notification includes a nil object and a userInfo dictionary containing the 
// begining and ending keyboard frame in screen coordinates. Use the various UIView and 
// UIWindow convertRect facilities to get the frame in the desired coordinate system. 
// Animation key/value pairs are only available for the "will" family of notification.

The last comment maybe it means "did" family of notification???

Upvotes: 3

Views: 561

Answers (1)

torof
torof

Reputation: 582

I had the same problem. It looks like the animate function has to be called from the main thread. Wrapping the animation in DispatchQueue.main.async worked for me:

@objc func keyboardWillHide(notification: NSNotification) {
    DispatchQueue.main.async {
        UIView.animate(withDuration: 2.0) {
            self.view.frame.origin.y = 0
        }
    }
}

Upvotes: 1

Related Questions