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

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

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

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

Q&A

解決済

2回答

495閲覧

TextViewに設定したViewをズラす設定がTextFieldにも適用されてしまう

ttah

総合スコア35

Swift

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

0グッド

0クリップ

投稿2020/02/26 13:06

編集2020/02/28 06:27

テキストビューをタッチ → 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

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

MasatoUchida

2020/02/27 09:55

変に省略するより、ある程度コードを載せて頂いた方が回答しやすく助かります。 また、UITextViewのeditableはfalseになっていますか?
ttah

2020/02/27 11:08

閲覧ありがとうございます。 可能な限りコードを付け足しました。 textfield,textviewに関連するところは一応全て載せました。 UITextViewのisEditableはfalseになっていません。 (textviewはテキスト入力を受付けなければなりません。)
MasatoUchida

2020/02/28 00:27

UITextViewの場合はキーボードを表示しずらし、UITextFieldの場合はキーボードを表示しずらしたくない、という認識であっていますでしょうか?
ttah

2020/02/28 01:26

はい。その通りです UITextViewを一度もタップしていなければ出来ていて、一度でもUITextViewをタップすると、UITextFieldタップでズレが生じます。 おそらくUITextViewタップでnotificationの通知がされその状態がUITextFieldタップで解除がうまく行っていないとかんがえています。 Extensionのnotification解除メソッドはlogで確認するとUITexyFieldタップで認識はされています
ttah

2020/02/28 06:31

hoshi-takanori様 すいません記述が漏れていました 質問のコードを修正しました UIVewControllerには, ScrollKeyBoard の記述があって記述があるのでUI Textviewで画面ズレができているのでScrollKeyBoardの適用はできているかなと考えています
guest

回答2

0

自己解決

すみません自己解決しました

func configureObserver() { let center = NotificationCenter.default let mainQueue = OperationQueue.main var token: NSObjectProtocol? var token1: NSObjectProtocol? token = center.addObserver(forName: UIResponder.keyboardWillShowNotification, object: nil, queue: mainQueue ) { (notification) in do { self.keyboardWillShow(notification) } center.removeObserver(token as Any) } token1 = center.addObserver(forName: UIResponder.keyboardWillHideNotification, object: nil, queue: mainQueue ) { (notification) in do { self.keyboardWillHide(notification) } center.removeObserver(token1 as Any) } }

投稿2020/02/28 14:57

ttah

総合スコア35

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

すいません、これはないわ

ちょっと思い出せないのですが、ncからfirstResponderを判別できませんでしたっけ?

例えば単純にtextFieldに対して無効にするなら、↓のように書いたらどうなるでしょうか?

swift

1 2guard let _ = notification.object as? UITextField else { return }

投稿2020/02/28 07:11

編集2020/02/28 07:16
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問