テキストフィールドの入力に応じてリアルタイムにLabelに表示させる、入力できる文字タイプに制限をかける、同じ文字の入力が◯文字以上続いた時に警告Labelを出す等々を実装してみました。参考に出来る部分があれば幸いです。
Storyboard
◎Main.storyboard
◎NextViewController.storyboard
NextViewControllerはめんどくさかったら作らなくてもOKです、ただ画面遷移処理部分が出来なくなるだけなので。
コード記述
RxSwiftをインストールしている前提なので先にインストールを忘れずに、、、
pod 'RxSwift', '6.5.0'
pod 'RxCocoa', '6.5.0'
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
@IBOutlet weak private var inputUserIDTextField: UITextField!
@IBOutlet weak private var mistakeUserIDLabel: UILabel!
@IBOutlet weak private var countUserIDCharactersLabel: UILabel!
@IBOutlet weak private var inputPasswordTextField: UITextField!
@IBOutlet weak private var mistakePasswordLabel: UILabel!
@IBOutlet weak private var signUpButton: UIButton! {
didSet {
signUpButton.layer.cornerRadius = 15.0 // ボタンを角丸にする
}
}
private let maxTextLength: Int = 10 // 最大入力文字数
private let minimumTextLength: Int = 6 // 最低入力文字数
private let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
configureInputUserIDTextField()
configurePasswordInputTextField()
configureSignUpButton()
}
private func configureInputUserIDTextField() {
inputUserIDTextField.rx.text.subscribe(onNext: { text in
if let text = text, text.count >= self.maxTextLength {
self.inputUserIDTextField.text = text.prefix(self.maxTextLength).description
}
let inputTextLength = self.inputUserIDTextField.text?.count ?? 0
let remainCount = self.maxTextLength - inputTextLength // 残り入力可能文字数
self.countUserIDCharactersLabel.text = "残り\(remainCount)文字"
self.signUpButton.isEnabled = (inputTextLength > 0)
guard let isMistakUserIDLabel = text?.isAlphanumeric() else { return }
if inputTextLength != 0 { // 文字の使用可否を判定する
self.mistakeUserIDLabel.isHidden = isMistakUserIDLabel
self.mistakeUserIDLabel.text = "使用できない文字が含まれています"
} else {
self.mistakeUserIDLabel.isHidden = true
}
}).disposed(by: disposeBag)
}
private func configurePasswordInputTextField() {
inputPasswordTextField.rx.text.subscribe(onNext: { text in
let inputTextLength = self.inputPasswordTextField.text?.count ?? 0
guard let isMistakePasswordLabal = text?.isCharacterString(text: text!) else { return }
if inputTextLength != 0 { // 3文字以上同じなら警告を出す
self.mistakePasswordLabel.isHidden = !isMistakePasswordLabal
self.mistakePasswordLabel.text = "予測されやすいパスワードです"
} else {
self.mistakePasswordLabel.isHidden = true
}
// 両方のTextFieldに入力がされていたら画面遷移を可能にする
self.signUpButton.isEnabled = (inputTextLength >= self.minimumTextLength) && self.inputUserIDTextField.text != ""
}).disposed(by: disposeBag)
}
private func configureSignUpButton() {
signUpButton.rx.tap.subscribe(onNext: {
let storyboard = UIStoryboard(name: "NextViewController", bundle: nil)
guard let nextViewController = storyboard.instantiateViewController(withIdentifier: "NextViewController") as? NextViewController else {
fatalError("遷移先がありません")
}
self.present(nextViewController, animated: true)
}).disposed(by: disposeBag)
}
}
extension String {
// 半角英数字を判定する関数
func isAlphanumeric() -> Bool {
return NSPredicate(format: "SELF MATCHES %@", "[a-zA-Z0-9]+").evaluate(with: self)
}
// 同じ文字が3文字以上連続しているかの判定をする関数
func isCharacterString(text: String) -> Bool {
if text.isEmpty { return false }
var sameCharacterCount = 0
var characterArray: [Character] = []
for index in text.description {
characterArray.append(index)
}
for i in 1 ..< text.count {
if characterArray[i - 1] == characterArray[i] {
sameCharacterCount += 1
} else {
sameCharacterCount = 0
}
}
return sameCharacterCount >= 2
}
}
まとめ
結論: RxSwiftは難しい
◎参考文献