web-dev-qa-db-ja.com

キーボードがビューの下部にあるテキストフィールドを覆っています

検索しました

ここ: キーボードが入力フィールドをカバーしている場合のみビューを上に移動します

ここ: キーボードがSwiftと表示されたらテキストフィールドを移動します

ここに: キーボードが存在するときにUITextFieldを上に移動させる方法?

そしてここ: https://developer.Apple.com/library/content/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html

残念ながら、すべてのリンク、そして私が見つけることができる他のすべての場所は、私が探している優れたクリーンなソリューションを提供しません。それらはObj-cコードで古くなっているか、Xcode 9 withSwift 4

ビューの下部にあるテキストフィールドをカバーしているキーボードをどのように管理しますか?キーボードがキーボードをカバーしている場合にのみ画面のビューを移動させますテキストフィールドビュー、スクロールビューを使用せず、これをアニメーション化して、単にスナップするのではなく見栄えをよくすることができ、最も重要なのは外部ライブラリを使用したくない

AppleのCoreAnimationライブラリは素晴らしいですが、すべてのサンプルコードは古く、この時点で非推奨となっているObjective Cに含まれています(Apple =ドキュメントを更新していません)。

Appleからの更新された最新のコードまたはライブラリを誰かが私に正しい方向に向けることができれば、この問題に具体的に対処するための欠けているものがあれば、それは大歓迎です。

4
flaaghara

このコードは機能し、フレームがキーボードのフレームと交差する場合、textFieldをキーボードの上にアニメーション化し、キーボード非表示の元の位置にアニメーション化します。

@IBOutlet weak var textField: UITextField!

  var offsetY:CGFloat = 0

  override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardFrameChangeNotification(notification:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
  }

  func keyboardFrameChangeNotification(notification: Notification) {
    if let userInfo = notification.userInfo {
      let endFrame = userInfo[UIKeyboardFrameEndUserInfoKey] as? CGRect
      let animationDuration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? Double ?? 0
      let animationCurveRawValue = (userInfo[UIKeyboardAnimationCurveUserInfoKey] as? Int) ?? Int(UIViewAnimationOptions.curveEaseInOut.rawValue)
      let animationCurve = UIViewAnimationOptions(rawValue: UInt(animationCurveRawValue))
      if let _ = endFrame, endFrame!.intersects(self.textField.frame) {
        self.offsetY = self.textField.frame.maxY - endFrame!.minY
        UIView.animate(withDuration: animationDuration, delay: TimeInterval(0), options: animationCurve, animations: {
          self.textField.frame.Origin.y = self.textField.frame.Origin.y - self.offsetY
        }, completion: nil)
      } else {
        if self.offsetY != 0 {
          UIView.animate(withDuration: animationDuration, delay: TimeInterval(0), options: animationCurve, animations: {
            self.textField.frame.Origin.y = self.textField.frame.Origin.y + self.offsetY
            self.offsetY = 0
          }, completion: nil)
        }
      }
    }
  }
4
SJ3040

IQKeyboardManagerSwiftを使用して、問題を簡単かつ迅速に解決できます。

Swift 4.をサポートするポッドファイルの以下のポッドを使用します。

pod 'IQKeyboardManagerSwift', '5.0.0'

ここにIQKeyboardManagerSwiftを実装するためのリンクがあります。

https://github.com/hackiftekhar/IQKeyboardManager

ありがとう!!!

7
Jaydeep Patel

このコードは私にとってはうまくいきました。

複数のテキストフィールドの場合

下部にあるテキストフィールドのみを実装しました(通知オブザーバーを使用せずに)。

scrollViewを使用している場合、このコードが役立つ場合があります(scrollViewDidScrollはオプションです)

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    scrollView.contentSize = CGSize(width: self.scrollView.frame.size.width, height: (scrollView.frame.size.height + 300))// To be more specific, I have used multiple textfields so wanted to scroll to the end.So have given the constant 300.
}

func textFieldDidBeginEditing(_ textField:UITextField) {
    self.scrollView.setContentOffset(textField.frame.Origin, animated: true)
}

そして、ビューに従ってテキストフィールドの位置を設定したい場合は、これを試してください:

func textFieldDidBeginEditing(_ textField:UITextField){
    textField.frame.Origin.y = textField.frame.Origin.y - 150 //(If have not used contentsizing the scroll view then exclude this line)default Origin takes the texfield to the top of the view.So to set lower textfields to proper position have used the constant 150.
    self.scrollView.setContentOffset(textField.frame.Origin, animated: true)
}

下部にあるテキストフィールド専用に行うこと。タグの値を確認してくださいtextfield.tag in textFieldDidBeginEditing

func textFieldDidBeginEditing(_ textField:UITextField){
    if textField.tag = 4 { //tag value of the textfield which are at the bottom
        self.scrollView.setContentOffset(textField.frame.Origin, animated: true)
    }
}

tableViewにテキストフィールドを実装した場合は、以下で説明する通知オブザーバーを使用してください。

tableViewに複数のテキストフィールドがある場合、できればNotification Observer

override func viewDidAppear(_ animated: Bool) {
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardDidShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardDidHide, object: nil)
}

@objc func keyboardWillShow(notification: NSNotification) {
    if let keyboardHeight = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.height {
        self.tableView.contentInset = UIEdgeInsetsMake(0, 0, keyboardHeight, 0)
    }
}

@objc func keyboardWillHide(notification: NSNotification) {
    UIView.animate(withDuration: 0.2, animations: {
        // For some reason adding inset in keyboardWillShow is animated by itself but removing is not, that's why we have to use animateWithDuration here
        self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
    })
}

deinit {
    print("denit")
    NotificationCenter.default.removeObserver(self)
}
2
Shalini K P

Uiviewに拡張機能を追加します。

import UIKit

//ビューをキーボードにバインドして拡張UIViewを変更します{

func bindToKeyboard(){
    NotificationCenter.default.addObserver(self, selector: #selector(UIView.keyboardWillChange(_:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
}



@objc func keyboardWillChange(_ notification: NSNotification) {
    let duration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
    let curve = notification.userInfo![UIKeyboardAnimationCurveUserInfoKey] as! UInt
    let curFrame = (notification.userInfo![UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue
    let targetFrame = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
    let deltaY = targetFrame.Origin.y - curFrame.Origin.y

    UIView.animateKeyframes(withDuration: duration, delay: 0.0, options: UIViewKeyframeAnimationOptions(rawValue: curve), animations: {
        self.frame.Origin.y += deltaY

    },completion: {(true) in
        self.layoutIfNeeded()
    })
}

}

0
Iulian David

私にとって完璧に機能しました: http://www.seemuapps.com/move-uitextfield-when-keyboard-is-presented

デリゲートが正しく設定されている場合、

 func textFieldDidBeginEditing(_ textField: UITextField) {
        moveTextField(textField, moveDistance: -250, up: true)
    }

    // Finish Editing The Text Field
    func textFieldDidEndEditing(_ textField: UITextField) {
        moveTextField(textField, moveDistance: -250, up: false)
    }

    // Hide the keyboard when the return key pressed
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }

    // Move the text field in a pretty animation!
    func moveTextField(_ textField: UITextField, moveDistance: Int, up: Bool) {
        let moveDuration = 0.3
        let movement: CGFloat = CGFloat(up ? moveDistance : -moveDistance)

        UIView.beginAnimations("animateTextField", context: nil)
        UIView.setAnimationBeginsFromCurrentState(true)
        UIView.setAnimationDuration(moveDuration)
        self.view.frame = self.view.frame.offsetBy(dx: 0, dy: movement)
        UIView.commitAnimations()
    }
0
ZameerMoh