質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

解決済

IBOutletで定義したNSLayoutConstraintの更新が反映されない

iosClimer
iosClimer

総合スコア20

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

2回答

0評価

0クリップ

185閲覧

投稿2022/04/25 02:24

編集2022/04/27 18:39

前提

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シミュレータで確認

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています