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

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

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

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

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

Q&A

解決済

2回答

4324閲覧

全てのTextFieldが空の時を判別したい

tarofess

総合スコア127

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

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

0グッド

1クリップ

投稿2017/01/11 23:37

編集2017/01/13 12:22

現在tableviewに複数のtextfieldがあり、全てのtextfieldが空の時は画面右上のbarbuttonitemをタップ不可にし、どれかに文字が1文字でも入るとbarbuttonitemをタップ可能にしたいのですが、以下のようにしてもうまくいきません。2文字目を入力した段階でbarbuttonitemがタップ可能になりますし、文字を全て消してもbarbuttonitemはタップ可能で、次に1文字入力するとbarbuttonitemがタップ不可能になるというように1アクション遅れます。

swift

1func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { 2 let filledTextFieldCells = self.tableView.visibleCells.filter { 3 if let cell = $0 as? Checkable { 4 return cell.isFilledTextField() 5 } else { 6 return false 7 } 8 } 9 if filledTextFieldCells.count == 0 { 10 self.navigationItem.rightBarButtonItem?.isEnabled = false 11 } else { 12 self.navigationItem.rightBarButtonItem?.isEnabled = true 13 } 14 15 return true 16 } 17 18class NameEditTableViewCell: UITableViewCell, Checkable { 19 20 @IBOutlet weak var nameTextField: UITextField! 21 22 func isFilledTextField() -> Bool { 23 return !self.nameTextField.text!.isEmpty ? true : false 24 } 25 26} 27

どうすれば入力と同時にtextfieldが空なのかどうかを判別することができるでしょうか?
どなたかわかる方がいれば教えていただきたいです。よろしくお願いします。

///回答を受けての追記///

swift

1func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { 2 let newText = (textField.text as! NSString).replacingCharacters(in: range, with: string) 3 4 let filledTextFieldCells = self.tableView.visibleCells.filter { 5 if let cell = $0 as? Checkable { 6 return cell.isFilledTextField(text: newText) 7 } else { 8 return false 9 } 10 } 11 if filledTextFieldCells.count == 0 { 12 self.navigationItem.rightBarButtonItem?.isEnabled = false 13 } else { 14 self.navigationItem.rightBarButtonItem?.isEnabled = true 15 } 16 17 return true 18 } 19 20extension Checkable { 21 func isFilledTextField(text: String) -> Bool { 22 return !text.isEmpty ? true : false 23 } 24}

///notificationを使ったやり方に変更///

swift

1func didChangeNotification(notification: Notification) { 2 var noEmptyTextField = true 3 4 if let textField = notification.object as? UITextField { 5 switch textField.tag { 6 case CellTag.name.rawValue: 7 if let text = textField.text, !text.isEmpty { 8 noEmptyTextField = true 9 } else { 10 noEmptyTextField = false 11 } 12 case CellTag.category.rawValue: 13 if let text = textField.text, !text.isEmpty { 14 noEmptyTextField = true 15 } else { 16 noEmptyTextField = false 17 } 18 case CellTag.price.rawValue: 19 if let text = textField.text, !text.isEmpty { 20 noEmptyTextField = true 21 } else { 22 noEmptyTextField = false 23 } 24 default: 25 break 26 } 27 } 28 29 if noEmptyTextField { 30 self.navigationItem.rightBarButtonItem?.isEnabled = true 31 } else { 32 self.navigationItem.rightBarButtonItem?.isEnabled = false 33 } 34 } 35

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

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

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

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

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

fuzzball

2017/01/12 23:43 編集

(deleted)
guest

回答2

0

ベストアンサー

以下のように記述することで判定できると思います、参考にしてみてください。

swift

1import UIKit 2 3class ViewController: UIViewController { 4 5 @IBOutlet weak var barButtonItem: UIBarButtonItem! 6 @IBOutlet weak var textField: UITextField! 7 @IBOutlet weak var textField2: UITextField! 8 9 override func viewDidLoad() { 10 super.viewDidLoad() 11 barButtonItem.isEnabled = false 12 13 // 入力値が変更された時に呼ばれる通知を登録 14 NotificationCenter.default.addObserver( 15 self, 16 selector: #selector(self.didChangeNotification(notification:)), 17 name: NSNotification.Name.UITextFieldTextDidChange, 18 object: nil 19 ) 20 } 21 22 var isInputTextField1 = false 23 var isInputTextField2 = false 24 var isInputTextField3 = false 25 26 // 入力値が変更された時に呼ばれるメソッド 27 func didChangeNotification(notification: Notification) { 28 29 if let textField = notification.object as? UITextField { 30 if let text = textField.text { 31 switch textField.tag { 32 case CellTag.name.rawValue : isInputTextField1 = text.isEmpty ? false : true 33 case CellTag.category.rawValue: isInputTextField2 = text.isEmpty ? false : true 34 case CellTag.price.rawValue : isInputTextField3 = text.isEmpty ? false : true 35 default: break 36 } 37 } 38 } 39 40 barButtonItem.isEnabled = isInputTextField1 || isInputTextField2 || isInputTextField3 ? true : false 41 } 42 43 // 通知の解除 44 deinit { 45 NotificationCenter.default.removeObserver(self) 46 } 47 48 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 49 view.endEditing(true) 50 } 51}

投稿2017/01/12 00:05

編集2017/01/13 13:17
_Kentarou

総合スコア8490

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

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

tarofess

2017/01/12 23:30

ご回答ありがとうございます。なるほど、NotificationCenterでもtextfieldの変化をハンドルできるんですね。しかしtextfieldが画面に複数あって、今の所うまくいってないです...。
_Kentarou

2017/01/13 00:06

回答を変更しました、通知のオブジェクトにUITextFieldのインスタンスが付いてくるのでどのテキストフィールドかは判断できます。
tarofess

2017/01/13 12:23

どのtextfieldのインスタンスなのか判別することはできるようになりました。しかし一つのtextfieldが空になるとbarButtonItemのenableがfalseになってしまいます。。。すみません、お手数をおかけしますが質問に現在詰まっている箇所のコードを追記しましたので、ご教授いただきたいです。
_Kentarou

2017/01/13 12:33

仕様が分からないのですが、複数あるTextFieldのうち一つでも入力があればボタンを押せるようにしたいと言うことですか?
tarofess

2017/01/13 12:38

はい、 複数textfieldがあり、一つでも入力があればボタンを押せるようにしたいです。今、一つでも入力があればボタンを押せるようになっているのですが、例えば二つのtextfieldに文字が入力されていて、その状態で一つのtextfieldの文字を全て消すとボタンが押せなくなってしまっています。
_Kentarou

2017/01/13 12:44

そのViewControllerクラスに変数として宣言してあるUITextFieldですか?
tarofess

2017/01/13 12:49

ViewControllerにUITextFieldの変数は宣言しておらず、UITableViewCellのサブクラス内でtextfieldは宣言しています。
_Kentarou

2017/01/13 13:19

強引ではありますがこのパターンに当てはめた実装で回答を修正しました、試してみてください。
tarofess

2017/01/13 13:33

ご提示のコードで動かすと期待していた動作になりました!最後まで親切に回答してくださり、誠にありがとうございます。助かりましたmm
guest

0

1アクション遅れるのは、textField(_:shouldChangeCharactersIn:replacementString:)の仕様を理解していないからです。この関数が呼ばれた時点ではテキストフィールドは更新されていません。

変更箇所(range)と変更内容(string)が渡されますので、元のテキストに対して、

swift

1let newText = (textField.text as NSString).replacingCharacters(in: range, with: string) 2//動作未確認(nilチェックなど全くしていません)

とすると、変更後の文字列を生成できます。

この辺りを考慮して作り直してみてはどうでしょうか?

投稿2017/01/12 01:03

fuzzball

総合スコア16731

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

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

tarofess

2017/01/12 23:44

ご回答ありがとうございます。shouldChangeCharactersInが呼ばれた時点でtextfieldは更新されないのですね。なのでご提示のコードを参考に修正してみたのですが、textfieldのどれか一つが空になるとbarbuttonitemがfalseになってしまいます。コードを追記したのですが、どこがおかしいでしょうか?
tarofess

2017/01/13 12:19

リンクの記事を見ると確かにshouldChangeCharactersInは使わない方が良さそうですね......。 notificationを使うことにします。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問