

ストーリーボードに素朴にUITextViewを置いています。

[code]

    import UIKit
    
    class ViewController: UIViewController, UITextViewDelegate {
        @IBOutlet weak var hogeTextView: UITextView!
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            self.hogeTextView.delegate = self
    
            NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChange), name: UIResponder.keyboardWillChangeFrameNotification, object: nil)
            NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
        }
    
        @objc func keyboardWillChange(notification: NSNotification) {
            guard let keyboardSize = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return }
    
            self.view.frame.origin.y = UIScreen.main.bounds.origin.y - keyboardSize.height
        }
    
        @objc func keyboardWillHide(notification: NSNotification) {
            guard self.view.frame.origin.y != 0 else { return }
    
            self.view.frame.origin.y = 0
        }
    
        func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
    
            if (text == "\n") {
                hogeTextView.resignFirstResponder()
                return false
            }
            return true
        }
    }
    
[/code]

上記コードについてです。

`self.view.frame.origin.y = UIScreen.main.bounds.origin.y -
keyboardSize.height`

の部分と

`self.view.frame.origin.y = 0`

についてアニメーション処理を入れていないにもかかわらず、キーボードがせり上がってくる速度と同じ速度で、`UITextView`がアニメーション付きでせり上がります（厳密にはせり上がっているのは
`self.view`）。何故でしょうか？


CC BY-SA 4.0
2019-06-04T04:33:42.613
55498
2019-06-04T14:54:46.310
2019-06-04T08:47:53.250
9008
9008
question
swift ios
アニメーション処理を書いてないにもかかわらず、キーボードに合わせてアニメーションするのは何故ですか？


いまSwiftをいじれる環境がないのでサッと解説します。

UIView の背後には CALayer があります。

[code]

    // UIView
    var layer: CALayer { get }
    
[/code]

この CALayer のインスタンスは描画に関する情報をもっていて、UIView はそれを元に画面にビューを描画します。CALayer
はこの描画を担当するオブジェクトをデリゲートとして参照します。

[code]

    // CALayer
    weak var delegate: CALayerDelegate? { get set }
    
[/code]

UIView の特定のプロパティの値の変更は CALayer のそれの変更にあたります。CALayer
は特定の値の変更に際し「暗黙のアニメーション」を実行します。

アニメーションもオブジェクトで、このアニメーションオブジェクトは CALayer のデリゲート、つまりここでは UIView が用意します。UIView は
CALayerDelegate プロトコルに適合し、実装するメソッドでそれを返します。

[code]

    // CALayerDelegate
    optional func action(for layer: CALayer, forKey event: String) -> CAAction?
    
[/code]

あなたが気にしているアニメーションはここで返されるアニメーションオブジェクトによって実行されています。  
標準では始点と終点のみを指定して 0.25 秒かけて描画されるアニメーションだったと思います。

* * *

### 参考

[action(forKey:) -
CALayerDelegate](https://developer.apple.com/documentation/quartzcore/calayerdelegate/2097264-action)

より詳しく基礎から学ぶ場合は [Core Animation Programming
Guide](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/CoreAnimation_guide/Introduction/Introduction.html)
をお読みください。


CC BY-SA 4.0
2019-06-04T14:54:46.310
55518
2019-06-04T14:54:46.310
2020-06-17T08:14:45.997
-1
55498
answer