前提
AutoLayoutの学習をしております。
一番下のTextFieldの編集時にキーボードに隠れないようにしたいです。
SuperViewとの制約をIBOutletに繋いで、キーボードの出現イベントに合わせて値を更新しようと思ってます。
実装方法
キーボードの高さを取得しTextFieldとSuperViewとの制約として更新する、という動きを期待してコードを書きました。
class ViewController: UIViewController { @IBOutlet weak var bottomCounstraintOfLastTextField: NSLayoutConstraint! override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: UIResponder.keyboardWillShowNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: UIResponder.keyboardWillHideNotification, object: nil) } } extension ViewController { ///キーボード出現のタイミングで下の制約を伸ばす @objc private func keyboardWillShow(_ notification: Foundation.Notification) { guard let info = notification.userInfo else { fatalError("Unexpected notification") } ///キーボードフレーム guard let keyboardFrame = info[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue else { fatalError("Found get Keyboard frame") } ///キーボードの高さ let keyboardHeight = keyboardFrame.cgRectValue.height ///キーボード表示アニメーションの時間を取得 guard let animationDuration = info[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double else { fatalError("Found get Keyboard Animation time")} ///制約を更新 bottomCounstraintOfLastTextField.constant = keyboardHeight ///アニメーションしてレイアウトを更新 UIView.animate(withDuration: animationDuration, animations: { () -> Void in self.view.layoutIfNeeded() }) } ///キーボードが無くなるタイミングで下の制約を39(元に戻す) @objc private func keyboardWillHide(_ notification: Foundation.Notification) { guard let info = notification.userInfo else { fatalError("Unexpected notification") } ///キーボード表示アニメーションの時間を取得 guard let animationDuration = info[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double else { fatalError("Found get Keyboard Animation time")} ///制約を更新 bottomCounstraintOfLastTextField.constant = 39 ///アニメーションしてレイアウトを更新 UIView.animate(withDuration: animationDuration, animations: { () -> Void in self.view.layoutIfNeeded() }) } ///viewをタップするとキーボードを下げる @IBAction func tapGesture(sender: AnyObject) { self.view.endEditing(true) } }
発生している問題
BreakPointで止めて制約の値が更新されてることは確認してます。
が、画面に反映されておらずキーボードに隠れてしまいます。
試したこと
2016年に発売された本を参考にしております。
ネットで調べて更新する処理を以下のコードに置き換えたらうまく更新されました。
///アニメーションしてレイアウトを更新 UIView.animate(withDuration: animationDuration, animations: { () -> Void in self.scrollView.contentInset.bottom = keyboardHeight self.scrollView.scrollIndicatorInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardHeight, right: 0) self.view.layoutIfNeeded() })
このコードで動いてますが、なぜ最初のコードでは反映されないかが気になります。
個人的にはIBOutletで繋いだ値を更新した方が直感的に分かりやすくて好きです。
補足情報(FW/ツールのバージョンなど)
Xcode13.3
iOS15.4シミュレータで確認
回答2件
あなたの回答
tips
プレビュー
下記のような回答は推奨されていません。
このような回答には修正を依頼しましょう。