1. ホーム
  2. swift

[解決済み] SwiftでuserInfoからキーボードの大きさを取得する

2023-05-21 09:11:34

質問

私はキーボードが表示されたときに私のビューを上に移動するいくつかのコードを追加しようとしてきました、しかし、私はSwiftにObjective-Cの例を翻訳しようとしている問題があります。私はいくつかの進歩を遂げましたが、私は1つの特定の行で立ち往生しています。

これらは、私が従ってきた2つのチュートリアル/質問です。

Swiftを使用してキーパッドが表示されたときにUIViewControllerのコンテンツを上に移動させる方法 http://www.ioscreator.com/tutorials/move-view-when-keyboard-appears

現在、私が持っているコードは以下の通りです。

override func viewWillAppear(animated: Bool) {
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
    NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
}

override func viewWillDisappear(animated: Bool) {
    NSNotificationCenter.defaultCenter().removeObserver(self)
}

func keyboardWillShow(notification: NSNotification) {
    var keyboardSize = notification.userInfo(valueForKey(UIKeyboardFrameBeginUserInfoKey))
    UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
    let frame = self.budgetEntryView.frame
    frame.origin.y = frame.origin.y - keyboardSize
    self.budgetEntryView.frame = frame
}

func keyboardWillHide(notification: NSNotification) {
    //
}

今のところ、この行でエラーが出ています。

var keyboardSize = notification.userInfo(valueForKey(UIKeyboardFrameBeginUserInfoKey))

もし誰かがこのコードの行がどうあるべきかを教えてくれれば、あとはなんとか自分で解決できるはずです。

どのように解決するのですか?

お使いの回線に問題があります。

var keyboardSize = notification.userInfo(valueForKey(UIKeyboardFrameBeginUserInfoKey))

  • notification.userInfo オプション 辞書 [NSObject : AnyObject]? , であるため、その値にアクセスする前にアンラップする必要があります。
  • Objective-Cの NSDictionary は Swift ネイティブの辞書にマッピングされるので は辞書の添え字構文 ( dict[key] ) を使って値にアクセスする必要があります。
  • 値をキャストする必要があります。 NSValue を呼び出すことができるように CGRectValue を呼び出すことができます。

これらすべては、オプショナルな割り当て、オプショナルな連鎖、オプショナルなキャストの組み合わせで実現することができます。

if let userInfo = notification.userInfo {
   if let keyboardSize = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
    let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
       // ...
   } else {
       // no UIKeyboardFrameBeginUserInfoKey entry in userInfo
   }
} else {
   // no userInfo dictionary in notification
}

あるいは1ステップで

if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
    let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
    // ...
}

Swift 3.0.1 (Xcode 8.1) に対応したアップデートを行いました。

if let userInfo = notification.userInfo {
    if let keyboardSize = userInfo[UIKeyboardFrameBeginUserInfoKey] as? CGRect {
        let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
        // ...
    } else {
        // no UIKeyboardFrameBeginUserInfoKey entry in userInfo
    }
} else {
    // no userInfo dictionary in notification
}

あるいは1ステップで

if let keyboardSize = notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? CGRect {
    let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
    // ...
}

Swift 5 (Xcode 11.6)に対応したアップデートです。

 guard let userInfo = notification.userInfo,
              let keyboardSize = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return }

を使うことをお勧めします。 keyboardFrameEndUserInfoKey の代わりに keyboardFrameBeginUserInfoKey に変更しました。これは、古い iOS デバイスでは、最初の表示後にキーボードが最初のレンダリングの高さを変更するためです。