

Keyboardに合わせて、Viewを移動させるアニメーションがうまくいきません。  
画像①~③のようにtextFieldをクリックした後にKeyboardが表示され、その上にViewが移動し表示されるのですが、Keyboardが表示されてから遅れてViewが移動してきます。  
また、Keyboardの文字を入力すると予測変換でViewが隠れてしまいます。  
原因の分かる方はアドバイスいただけると助かります。  
①  
[![①](https://i.stack.imgur.com/OV6vO.png)](https://i.stack.imgur.com/OV6vO.png)  
②  
[![②](https://i.stack.imgur.com/0l1bd.png)](https://i.stack.imgur.com/0l1bd.png)  
③  
[![③](https://i.stack.imgur.com/JNM4v.png)](https://i.stack.imgur.com/JNM4v.png)

ソースは以下のようになっています。

[code]

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)
        NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillShowNotification), name: Notification.Name.UIKeyboardDidShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(handleKeybordWillHideNotification), name: Notification.Name.UIKeyboardDidHide, object: nil)
    }
    
    func handleKeyboardWillShowNotification(_ notification: Notification){
        let keyboardFrame = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue
        let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey]
    
        UIView.animate(withDuration: duration as! TimeInterval, animations: {
            //self.view.frame.origin.y = -(keyboardFrame?.height)!
            let transform = CGAffineTransform(translationX: 0, y: -(keyboardFrame?.size.height)!)
            self.view.transform = transform
            //self.view.layoutIfNeeded()
        },completion:nil)
    }
    
    func handleKeybordWillHideNotification(_ notification: Notification){
        let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as! Double
        UIView.animate(withDuration: duration, animations: {
            //self.view.frame.origin.y = 0
            let transform = CGAffineTransform (translationX: 0, y: 0)
            self.view.transform = transform
            //self.view.layoutIfNeeded()
        },completion:nil)
    }
    
[/code]


CC BY-SA 3.0
2016-10-31T14:56:59.910
30020
2016-11-01T01:18:15.673
18492
question
xcode swift3
Keyboardに合わせて、Viewを移動させたい！


> Keyboardが表示されてから遅れてViewが移動してきます。

以下のように、受け取るNotificationを変更することで、解決するようです。

[code]

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)
        // Notification.Name.UIKeyboardDidShow -> .UIKeyboardWillShow
        NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardWillShowNotification), name: Notification.Name.UIKeyboardWillShow, object: nil)
        // Notification.Name.UIKeyboardDidHide -> UIKeyboardWillHide
        NotificationCenter.default.addObserver(self, selector: #selector(handleKeybordWillHideNotification), name: Notification.Name.UIKeyboardWillHide, object: nil)
    }
    
[/code]

> Keyboardの文字を入力すると予測変換でViewが隠れてしまいます。

これも、受け取ったNotificationから取得する情報を変更すればいいようです。

[code]

    func handleKeyboardWillShowNotification(_ notification: Notification){
        // UIKeyboardFrameBeginUserInfoKey -> UIKeyboardFrameEndUserInfoKey
        let keyboardFrame = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
        let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey]
    
        UIView.animate(withDuration: duration as! TimeInterval, animations: {
            let transform = CGAffineTransform(translationX: 0, y: -(keyboardFrame?.size.height)!)
            self.view.transform = transform
        },completion:nil)
    }
    
[/code]

イベントが起きる前と、起きた後のNotification、NotificationのInfoを、どう採用するかで、細かな挙動が変化するのですね。  
以下、変更をまとめておきました。

[code]

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)
    
        NotificationCenter.default.addObserver(self, selector: #selector(ViewController.handleKeyboardWillShowNotification(_:)), name: .UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(ViewController.handleKeybordWillHideNotification(_:)), name: .UIKeyboardWillHide, object: nil)
    }
    
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
    
        NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
        NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
    }
    
    func handleKeyboardWillShowNotification(_ notification: Notification){
        guard let keyboardFrame = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue,
            let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? TimeInterval else {
                return
        }
    
        UIView.animate(withDuration: duration, animations: {
            let transform = CGAffineTransform(translationX: 0, y: -(keyboardFrame.size.height))
            self.view.transform = transform
        }, completion: nil)
    }
    
    func handleKeybordWillHideNotification(_ notification: Notification){
        guard let duration = notification.userInfo?[UIKeyboardAnimationDurationUserInfoKey] as? Double else {
            return
        }
    
        UIView.animate(withDuration: duration, animations: {
            let transform = CGAffineTransform (translationX: 0, y: 0)
            self.view.transform = transform
        }, completion: nil)
    }
    
[/code]


CC BY-SA 3.0
2016-11-01T01:18:15.673
30023
2016-11-01T01:18:15.673
18540
30020
answer