テキストビューをタッチ → viewがズレてキーボードを出す キーボードが消えたらviewが戻る
↑の挙動が1度テキストビューをタップしてしまうとテキストフィールドでも起こってしまいます
extensionにする前にviewcontrollerに書いてたときはこの症状は起こりませんでした
挙動的にはNotificationCenterの解除が機能していない?と思うのですが解決策が見つからない状態です。
現在のコード
extension
1protocol ScrollKeyBoard { 2 func configureObserver() 3 func removeObserver() 4} 5 6extension ScrollKeyBoard where Self: UIViewController { 7 8 9 func configureObserver() { 10 NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillShowNotification, object: nil, queue: nil) { (notification) in 11 self.keyboardWillShow(notification) 12 } 13 NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillHideNotification, object: nil, queue: nil) { notification in 14 self.keyboardWillHide(notification) 15 } 16 } 17 18 // キーボードが現れたときにviewをずらす 19 func keyboardWillShow(_ notification: Notification) { 20 let rect = (notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue 21 let duration: TimeInterval? = notification.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double 22 UIView.animate(withDuration: duration!) { 23 self.view.transform = CGAffineTransform(translationX: 0, y: -(rect?.size.height)!) 24 } 25 } 26 27 // キーボードが消えたときにviewを戻す 28 func keyboardWillHide(_ notification: Notification) { 29 let duration: TimeInterval? = notification.userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as? Double 30 UIView.animate(withDuration: duration!) { 31 self.view.transform = CGAffineTransform.identity 32 } 33 } 34 35 func removeObserver() { 36 NotificationCenter.default.removeObserver(self) 37 } 38}
UIViewController
1 2import UIKit 3 4class UserDataInputViewController: UIViewController, UINavigationControllerDelegate ,UIImagePickerControllerDelegate, UITextViewDelegate, UITextFieldDelegate, UIScrollViewDelegate, ScrollKeyBoard { 5 6 @IBOutlet weak var textField: UITextField! 7 @IBOutlet weak var textView: UITextView! 8 9 override func viewDidLoad() { 10 super.viewDidLoad() 11 textField.delegate = self 12 textField.delegate = self 13 } 14 15 16 17 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 18 if isTouch(touches: touches, view: TextView) { 19 configureObserver() 20 } 21 } 22 23 func isTouch(touches: Set<UITouch>, view:UIView) -> Bool{ 24 for touch: AnyObject in touches { 25 let t: UITouch = touch as! UITouch 26 if t.view?.tag == view.tag { 27 return true 28 } 29 } 30 return false 31 } 32 33 func textFieldDidBeginEditing(_ textField: UITextField) { 34 removeObserver() 35 }
一応機能していたコード
UIViewController
1 func configureObserver() { 2 3 let notification = NotificationCenter.default 4 notification.addObserver( 5 self, 6 selector: #selector(self.keyboardWillShow(notification:)), 7 name: UIResponder.keyboardWillShowNotification, 8 object: nil 9 ) 10 notification.addObserver( 11 self, 12 selector: #selector(self.keyboardWillHide(notification:)), 13 name: UIResponder.keyboardWillHideNotification, 14 object: nil 15 ) 16 } 17 //Notificationを削除 18 func removeObserver() { 19 NotificationCenter.default.removeObserver(self) 20 } 21 22 //キーボードが現れたときにviewをずらす 23 @objc func keyboardWillShow(notification: Notification?) { 24 let rect = (notification?.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue 25 let duration: TimeInterval? = notification?.userInfo?[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double 26 UIView.animate(withDuration: duration!) { 27 self.view.transform = CGAffineTransform(translationX: 0, y: -(rect?.size.height)!) 28 } 29 } 30 //キーボードが消えたときにviewを戻す 31 @objc func keyboardWillHide(notification: Notification?) { 32 let duration: TimeInterval? = notification?.userInfo?[UIResponder.keyboardAnimationCurveUserInfoKey] as? Double 33 UIView.animate(withDuration: duration!) { 34 self.view.transform = CGAffineTransform.identity 35 } 36 } 37 38 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 39 if isTouch(touches: touches, view: TextView) { 40 configureObserver() 41 } 42 } 43 44 func isTouch(touches: Set<UITouch>, view:UIView) -> Bool{ 45 for touch: AnyObject in touches { 46 let t: UITouch = touch as! UITouch 47 if t.view?.tag == view.tag { 48 return true 49 } 50 } 51 return false 52 } 53 54 func textFieldDidBeginEditing(_ textField: UITextField) { 55 removeObserver() 56 } 57
変に省略するより、ある程度コードを載せて頂いた方が回答しやすく助かります。
また、UITextViewのeditableはfalseになっていますか?
閲覧ありがとうございます。
可能な限りコードを付け足しました。
textfield,textviewに関連するところは一応全て載せました。
UITextViewのisEditableはfalseになっていません。
(textviewはテキスト入力を受付けなければなりません。)
UITextViewの場合はキーボードを表示しずらし、UITextFieldの場合はキーボードを表示しずらしたくない、という認識であっていますでしょうか?
はい。その通りです
UITextViewを一度もタップしていなければ出来ていて、一度でもUITextViewをタップすると、UITextFieldタップでズレが生じます。
おそらくUITextViewタップでnotificationの通知がされその状態がUITextFieldタップで解除がうまく行っていないとかんがえています。
Extensionのnotification解除メソッドはlogで確認するとUITexyFieldタップで認識はされています
class ViewController: UIViewController, ScrollKeyBoard { ... } とする必要があるのでは?
https://qiita.com/crea/items/4297bf60d222d661498f#where%E3%81%8C%E4%BB%98%E5%8A%A0%E3%81%95%E3%82%8C%E3%81%9F%E5%A0%B4%E5%90%88-1
hoshi-takanori様
すいません記述が漏れていました
質問のコードを修正しました
UIVewControllerには, ScrollKeyBoard の記述があって記述があるのでUI Textviewで画面ズレができているのでScrollKeyBoardの適用はできているかなと考えています
回答2件
あなたの回答
tips
プレビュー