キーボードで入力欄が隠れないように対応[Swift4]

昨日、アプリ1つ、できた!!と思ったが

iPhone SEとかの画面ではキーボードが表示されると

画面の一部が隠れてしまい

ボタンが見えなくなったり

別のテキストビューが見えなくなったりするので

修正が必要だということに気付いた。

キーボード以外のところを

クリックしたらキーボードを非表示にする、というのは

割と簡単にできた。

| Swift:画面をタップすることでキーボードを閉じる処理の2パターン
Swift3でキーボードをタップした際にキーボードを閉じる処理をなんと2パターン書いていこうかと思います。   キーボードを閉じる処理 キーボードを閉じる処理はアプリ開発をする際、 必須の機能ですよね! 入力が完了した時に閉じる処理や ボタンをタップした時に閉じる処理などは記述し易いですが、 Viewをタップした時の処...
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        self.view.endEditing(true)
    }

あとは

テキストビューにキーボードが重なって見えなくなるのを

直さないといけない。

のだけど

その方法を探し中。

キーボードの上までテキストビューを移動させる方法は載ってたけど

そのまま使うと、大きい画面の時も移動してしまうし

元の位置に戻せなかった。

別の方法もあるみたいなので

試してみようと思う。

ーーーーーー

あれこれやってみたけど

資料が古いのかなかなかうまくいかない。

結局、これが一番まともに動くので、

元の位置に戻すことができるようになれば

使えると思う。

【Swift】キーボードと被らないようにUITextViewをずらす方法。 | はじはじアプリ体験記
UITextFieldやUITextViewがキーボードと被って見えなくならないために、キーボードと被ったぶんだけビューを上に移動する方法をサンプルを使いながら説明します。NSNotificationCenterから通知を受けたらビューの制約を更新してアニメーションの中で移動させます。

Swift2.1の情報なのでそのままでは使えない。

とりあえずキーボードに閉じるボタンはつけないで

テキストビューを移動させて元に戻す、という処理だけ使うことにする。

ここも参考に

CGRectの新旧書き方対応表 - The Pragmatic Ball boy
古 新 CGRectGetWidth( rect ) rect.width CGRectGetHeight( rect ) rect.height CGRectGetMinX( rect ) rect.minX CGRectGetMidX( rect ) rect.midX CGRectGetMaxX( rect ) ...
[Swift3.0] NotificationCenterでキーボード表示時にその高さを取得する - JoyPlotドキュメント
UITextField などをタップした時に出現するキーボードの高さを取得したいという場合があります。 これは、キーボード出現時に NotificationCenter で通知を送る設定をすることで実現できます。 キーボードの高さを取得するサンプルソースコード

これも参考にしながら書き直している。

できたらソースコードを載せる予定。

今、逆方向に動いてる。(テキストビューとキーボードがさらに重なるw)

[Swift3.0] NotificationCenter を使ってアプリの状態に応じた処理を行う - JoyPlotドキュメント
NotificationCenter を使って、アプリの状態がバックグラウンドになった時や、フォアグラウンド(アクティブ)に戻った時などに特定の処理を行わせる方法です。 アプリの状態に応じて呼び出されるメソッド プロジェクト作成時に自動的に作られる AppDelegate.swift

できた!!! (object-cのような気がするのは気にしない方向で)

import UIKit

class YNFirstViewController: UIViewController, UITextViewDelegate {

    

    @IBOutlet weak var ynTextView: CustomTextView!

    

    @IBOutlet weak var textConstraintsY: NSLayoutConstraint!

    

    var allY:CGFloat = 0.0

    

    override func viewDidLoad() {

        super.viewDidLoad()

        

        //テキストビューのデリゲート先にこのインスタンスを設定する。

        ynTextView.delegate = self

        

        //キーボードが現れるときに通知するメソッドを登録する。

        // NotificationCenterの設定

        // 第3引数 name に NSNotification.Name.UIKeyboardDidShow を設定することで、キーボード出現後に通知を行うメソッドを設定できる。

        NotificationCenter.default.addObserver(

        self,

        selector: #selector(self.showKeyboard(notification:)),

        name: NSNotification.Name.UIKeyboardDidShow,

        object: nil

        )

        

        NotificationCenter.default.addObserver(

            self,

            selector: #selector(self.hideKeyboard(notification:)),

            name: NSNotification.Name.UIKeyboardDidHide,

            object: nil

        )

    }

    

    // キーボードの情報を受け取るメソッドを設定

    // キーボード出現後に、第2引数として登録した以下のメソッド showKeyboard(notification:) が呼び出される

    // このとき、このメソッドの引数 notification の userInfo にキーボードに関する情報が含まれています。

    @objc func showKeyboard(notification: Notification) {

        //キーボードのフレームを取得する。

        if let keyboardFrame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as AnyObject).cgRectValue {

            

            //テキストビューの最大Y座標と、キーボードの最小Y座標の差を計算する。

            let zureY = (ynTextView.frame).maxY – (keyboardFrame).minY

            

            if (zureY > 0) {

                //テキストビューの垂直方向の位置の制約に差分をプラスする。

                textConstraintsY.constant -= zureY

                allY -= zureY

                

                //アニメーションさせる。

                UIView.animate(withDuration: 0.5, animations:{ self.view.layoutIfNeeded()})

            }

        }

    }

    //キーボードが閉じられるときの呼び出しメソッド

  @objc func hideKeyboard(notification: Notification) {

        //テキストビューの位置を元に戻す。        

        if(allY < 0) {

           textConstraintsY.constant -= allY

        

            UIView.animate(withDuration: 0.5, animations:{ self.view.layoutIfNeeded()})

        }

        allY = 0.0

    }

        

    // キーボード以外のところをタップしたらキーボードを非表示にする処理

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        self.view.endEditing(true)

    }

}