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

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

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

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

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

Q&A

解決済

1回答

535閲覧

UITextFieldの文字数を正確にカウントしたい

HideakiOshima

総合スコア16

iOS

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

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

1グッド

2クリップ

投稿2017/07/03 03:54

###前提・実現したいこと
パスワード入力欄(6文字以上15文字以内)をUITextFieldで実装し、入力された文字数が6文字未満の時にログインボタンを無効にしたい

###発生している問題
現在、上記のことを実現すべく実装をしているのですが、パスワードを入力して6文字以上入力したらボタンを有効化することは達成できました。
しかし、6文字以上入力した後に文字を消していくと何故か4文字になった時に5文字判定(実際の文字数+1)になりボタンを無効にするタイミングがずれてしまいます。
文字を削除していった時にtext fieldの文字数を正しくカウントするにはどうしたら良いでしょうか?
よろしくお願いします。

###該当のソースコード
パスワード入力用のtext field以外にメール入力用のtext fieldもあります。

Swift

1import UIKit 2 3final class LoginView: UIView { 4 5 private lazy var iconImageView: UIImageView = { 6 let imageView = UIImageView() 7 imageView.image = UIImage(named: "Icon") 8 self.addSubview(imageView) 9 return imageView 10 }() 11 12 lazy var mailTextField: UITextField = { 13 let textField = UITextField() 14 textField.delegate = self 15 textField.tag = 0 16 textField.placeholder = "メールアドレス" 17 textField.borderStyle = .roundedRect 18 textField.font = UIFont.hiraginoSans(ofSize: 15) 19 textField.keyboardType = .emailAddress 20 self.addSubview(textField) 21 return textField 22 }() 23 24 lazy var passwordTextField: UITextField = { 25 let textFeild = UITextField() 26 textFeild.delegate = self 27 textFeild.tag = 1 28 textFeild.borderStyle = .roundedRect 29 textFeild.placeholder = "パスワード(6文字以上15文字以下)" 30 textFeild.font = UIFont.hiraginoSans(ofSize: 15) 31 textFeild.keyboardType = .default 32 textFeild.isSecureTextEntry = true 33 self.addSubview(textFeild) 34 return textFeild 35 }() 36 37 lazy var finishButton: UIButton = { 38 let button = UIButton() 39 button.backgroundColor = Color.main 40 button.layer.cornerRadius = 4 41 button.titleLabel?.font = UIFont.boldHiraginoSans(ofSize: 16) 42 button.isEnabled = false 43 button.alpha = 0.5 44 self.addSubview(button) 45 return button 46 }() 47 48 override init(frame: CGRect) { 49 super.init(frame: frame) 50 } 51 52 required init?(coder aDecoder: NSCoder) { 53 fatalError("init(coder:) has not been implemented") 54 } 55 56 override func layoutSubviews() { 57 iconImageView.frame = CGRect(x: self.frame.width / 2 - 76, y: 46, width: 152, height: 40) 58 mailTextField.frame = CGRect(x: 20, y: 121, width: self.frame.width - 40, height: 35) 59 passwordTextField.frame = CGRect(x: 20, y: 173, width: self.frame.width - 40, height: 35) 60 finishButton.frame = CGRect(x: 20, y: 242, width: self.frame.width - 40, height: 43) 61 } 62 63 func mailVaridation(textField: UITextField) -> Bool { 64 let emailRegEx = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}" 65 let emailTest = NSPredicate(format:"SELF MATCHES %@", emailRegEx) 66 let result = emailTest.evaluate(with: textField.text) 67 if result == false { 68 textField.text = nil 69 textField.placeholder = "形式が正しくありません" 70 71 return false 72 73 } else { 74 75 return true 76 77 } 78 } 79 80 func passwordValidator(textField: UITextField) -> Bool { 81 let minLength = 6 82 let text = textField.text! 83 84 if text.characters.count < minLength { 85 textField.text = nil 86 textField.placeholder = "6文字以上15文字以下でご入力ください" 87 88 return false 89 90 } else { 91 92 return true 93 94 } 95 } 96 97} 98 99extension LoginView: UITextFieldDelegate { 100 101 func textFieldShouldReturn(_ textField: UITextField) -> Bool { 102 103 textField.resignFirstResponder() 104 105 return true 106 } 107 108 func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { 109 110 var mailResult = false 111 112 if textField.tag == 1 { 113 let maxLength = 15 114 let text = textField.text! + string 115 116 if mailTextField.text?.isEmpty == false { 117 mailResult = mailVaridation(textField: mailTextField) 118 } 119 120 //ここの判定がうまく行きません 121 if (text.characters.count < 6 && mailResult == true) || 122 (text.characters.count < 6 && mailResult == false) || 123 (text.characters.count >= 6 && mailResult == false) { 124 finishButton.isEnabled = false 125 finishButton.alpha = 0.5 126 } else if text.characters.count >= 6 && mailResult == true { 127 finishButton.isEnabled = true 128 finishButton.alpha = 1 129 } 130 if text.characters.count <= maxLength { 131 return true 132 } 133 return false 134 135 } 136 return true 137 138 } 139 140 func textFieldDidEndEditing(_ textField: UITextField) { 141 142 var mailResult = false 143 var passwordResult = false 144 145 if mailTextField.text?.isEmpty == false { 146 mailResult = mailVaridation(textField: mailTextField) 147 } 148 149 if passwordTextField.text?.isEmpty == false { 150 passwordResult = passwordValidator(textField: passwordTextField) 151 } 152 153 if mailResult == true && passwordResult == true { 154 finishButton.isEnabled = true 155 finishButton.alpha = 1 156 } else { 157 finishButton.isEnabled = false 158 finishButton.alpha = 0.5 159 } 160 161 } 162 163} 164

###補足情報(言語/FW/ツール等のバージョンなど)
swift3 Xcode8

Hyperbolic4183👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

swift

1let text = textField.text! + string

単純に後ろにくっつけるのではダメです。バックスペースだと分かりにくいですが、カーソル移動して文字列の途中に入力してみればダメなことは一目瞭然です。

正しくは、rangeで示される文字列をstringで置き換えないといけません。

Stringでやると面倒臭そうなので、NSStringにキャストしてreplacingCharacters(in:with:)を使っています。

swift

1let text = (textField.text! as NSString).replacingCharacters(in: range, with: string)

投稿2017/07/03 05:17

fuzzball

総合スコア16731

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

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

HideakiOshima

2017/07/03 05:56

単純に後ろにつけるのではだめなのですね! 気づきませんでした! ご指摘どおりにコードを変えた所、しっかりと動きました!ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問