8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ZOZOテクノロジーズ #1Advent Calendar 2019

Day 14

【iOS】簡単にKeyboardを表示したときにTextFieldが隠れないようにする

Posted at

この記事は ZOZOテクノロジーズ #1 Advent Calendar 2019 14日目の記事になります。
昨日の記事は @hkame さんによる「Aurora->CloudSQLへMySQLレプリケーションはできるのか」でした。

はじめに

本記事はKeyboardを表示したときにTextFieldが隠れてしまわないようにするための実装についてです。
TextFieldが隠れないようにする実装のやり方は色々あると思いますが、本記事ではFrame計算などのない簡単な方法を紹介したいと思います。

結果

このような動きになります。
日本語キーボードにしてキーボードの高さが変わってもTextFieldの位置が変わっているのがいいですね。

demo.gif

実装について

実装は単純で、キーボードが表示されたらScrollViewのcontentInset.bottomの値を調整します。

ポイントとしては、contentOffsetの調整ではなく、contentInsetの値を調整することです。
contentInsetの値を調整するメリットは、TextFieldの表示位置を気にしなくてもいいことです。
contentOffsetの値を変更する際に単純にキーボードの高さを足してしまうと、TextFieldの位置の制御をするためにキーボードがどの位置に表示されているかにより設定するcontentOffsetを求める計算が必要になります。

contentOffset.yにキーボードの高さを足した場合 contentInset.bottomにキーボードの高さを足した場合
Dec-14-2019 00-35-40.gif Dec-14-2019 00-27-48.gif
import UIKit

class ViewController: UIViewController {
   
    @IBOutlet private weak var scrollView: UIScrollView!
    @IBOutlet private weak var nicknameTextField: UITextField!
    @IBOutlet private weak var birthdayTextField: UITextField!
    @IBOutlet private weak var submitButton: UIButton!
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidAppear(_:)), name: UIResponder.keyboardDidShowNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillDisappear(_:)), name: UIResponder.keyboardWillHideNotification, object: nil)
    }

    @objc private func keyboardDidAppear(_ notification: Notification) {
        guard let keyboardFrame = (notification.userInfo?["UIKeyboardFrameEndUserInfoKey"] as? NSValue)?.cgRectValue else { return }

        scrollView.contentInset.bottom = keyboardFrame.height
    }

    @objc private func keyboardWillDisappear(_ notification: Notification) {
        scrollView.contentInset.bottom = 0
    }
}

キーボードの高さの監視タイミングについて

キーボードの表示、非表示のタイミングをそれぞれまとめてみました。

キーボードの表示

keyboardWillAppear keyboardDidShowNotification
Dec-14-2019 00-43-12.gif Dec-14-2019 00-48-45.gif

|

キーボードの非表示

keyboardWillAppear keyboardDidShowNotification
Dec-14-2019 00-49-38.gif Dec-14-2019 00-46-07.gif

|

まとめ

キーボードを表示した際にTextFieldを隠れないようにするには、scrollViewのcontentInset.bottomの値を変更する実装がとても簡単です。
キーボードの非表示時監視タイミングをkeyboardDidShowNotificationにするとカクつくのでおすすめしません。

明日の記事は @r-tezuka さんによる公開予定です。どうぞお楽しみに。

8
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?