今回はTextFieldがキーボードに隠れてしまう問題の解決方法をメモしていきます。
Udemyのオススメの講座
Contents
TextFieldがキーボードに隠れてしまう問題
誰もが一度は引っかかる問題ですよね・・・
解決例
- そもそもTextFieldを下に置かない。
- LINEみたいにTextFieldをキーボードの高さ分を上に移動させる。←今回はこれをやります!
それではコードを書いていきます!
トータルのコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
// // ViewController.swift // TextFieldShow import UIKit class ViewController: UIViewController { let SCREEN_SIZE = UIScreen.main.bounds.size @IBOutlet weak var textField: UITextField! override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil) //ここでUIKeyboardWillShowという名前の通知のイベントをオブザーバー登録をしている NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide(_:)), name: NSNotification.Name.UIKeyboardDidHide, object: nil) //ここでUIKeyboardWillHideという名前の通知のイベントをオブザーバー登録をしている } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } //Viewをタップした時に起こる処理を描く関数 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { //キーボードを閉じる処理 view.endEditing(true) } //UIKeyboardWillShow通知を受けて、実行される関数 func keyboardWillShow(_ notification: NSNotification){ let keyboardHeight = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as AnyObject).cgRectValue.height textField.frame.origin.y = SCREEN_SIZE.height - keyboardHeight - textField.frame.height } //UIKeyboardWillShow通知を受けて、実行される関数 func keyboardWillHide(_ notification: NSNotification){ textField.frame.origin.y = SCREEN_SIZE.height - textField.frame.height } } |
let SCREEN_SIZE = UIScreen.main.bounds.size
スクリーンサイズを取ってきています。
後々効いてきます!
NotificationCenter.defaults.addObserver
ここが複雑ですよね・・・・とりあえず使い方はこんな感じです!!
NotificationCenter.default.addObserver(通知を受け取るオブジェクト, selector: #selector(通知を受け取った時に実行される関数), name: 受け取る通知の名前, object: nil)
textFieldをタップ
↓
keyboardwillshow(これからキーボード出るよ〜〜!)という通知が送られる。
↓
通知を受け取るオブジェクトは『ViewController』ですね。
↓
通知を受け取った時に実行される関数(func keyboardWillShow(_ notification: NSNotification){} )が実行されます。
func keyboardWillShow(_ notification: NSNotification){} の中身
とっても単純です。
飛び出るキーボードの高さを取得して、
let keyboardHeight = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as AnyObject).cgRectValue.height
キーボードとtextFieldの高さをスクリーンサイズから引いた値をtextFieldのy軸の座標にしています。
textField.frame.origin.y = SCREEN_SIZE.height – keyboardHeight – textField.frame.height
どうですか??
以外に面倒ですよね。笑
素晴らしい記事をありがとうございます!
質問なのですが、
textField.becomeFirstResponder() 等でユーザーの操作なくキーボードを表示させた場合、func keyboardWillShowの処理を、適応することはできますか?
返信いただけると嬉しいです。
コメントありがとうございます!
こちらでUIButtonを適当に配置して、そのUIButtonのアクション内でbecomeFirstResponder()を叩いてみたところfunc keyboardWillShowも呼ばれました。
コードはこちらです。Swift4.1です。
import UIKit
class ViewController: UIViewController {
let SCREEN_SIZE = UIScreen.main.bounds.size
@IBOutlet weak var textField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
//ここでUIKeyboardWillShowという名前の通知のイベントをオブザーバー登録をしている
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide(_:)), name: NSNotification.Name.UIKeyboardDidHide, object: nil)
//ここでUIKeyboardWillHideという名前の通知のイベントをオブザーバー登録をしている
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
//Viewをタップした時に起こる処理を描く関数, with event: UIEvent?) {
override func touchesBegan(_ touches: Set
//キーボードを閉じる処理
view.endEditing(true)
}
//UIKeyboardWillShow通知を受けて、実行される関数
@objc func keyboardWillShow(_ notification: NSNotification){
let keyboardHeight = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as AnyObject).cgRectValue.height
textField.frame.origin.y = SCREEN_SIZE.height - keyboardHeight - textField.frame.height
}
@IBAction func actionButton(_ sender: Any) {
textField.becomeFirstResponder()
}
//UIKeyboardWillShow通知を受けて、実行される関数
@objc func keyboardWillHide(_ notification: NSNotification){
textField.frame.origin.y = SCREEN_SIZE.height - textField.frame.height
}
}