14
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

SwiftUI: TextFieldでCombineを使用し、テキストフィールドの変更に関する更新を取得します。

Last updated at Posted at 2021-01-16

CombineをSwiftUI TextFieldと一緒に使用することで、テキストフィールド TextField に入力されたコンテンツユーザーに関する更新を取得することができます。

この記事では、以下について説明します。

  • Combineを使用してTextFieldの変更を監視する
  • ユーザーがテキストフィールドに入力できる文字数の制限
  • ユーザーのパスワードに最低限の大文字、記号、数字が含まれているかどうか、更に文字数制限を超えていないかどうかを確認する。

##Combineを使用してTextFieldの変更を監視する

コードは簡単です。まず、Combine フレームワークをインポートする必要があります。それから .onReceive(Just(messageText)) ビューモディファイアーを TextField へ追加してください。

完全なコードはこちらです:

import SwiftUI
import Combine

struct ContentView: View {
    @State var messageText: String = ""
    var body: some View {
        Form {
            TextField("Message", text: $messageText)
                .onReceive(Just(messageText)) { _ in
                    // テキストを変更する場合にはこちらにコードを入力して下さい
                }
                .padding()
        }
    }
}

これで .onReceive ブロックのコードは、テキストコンテンツが変わる度に呼び出されるようになります。

この記事は、上記のコードを使って追加することができるいくつかの機能性についても解説します。

ユーザーがテキストフィールドに入力できる文字数の制限

ユーザーが SwiftUI TextField に入力することのできる文字数を制限する場合があります。もしユーザーが制限を超える文字を入力する場合は、余分なテキストを削除することもあります。

import SwiftUI
import Combine

struct ContentView: View {
    @State var messageText: String = ""
    var body: some View {
        Form {
            TextField("メッセージ", text: $messageText)
                .onReceive(Just(messageText)) { _ in
                    if messageText.count > 30 {
                        messageText = String(messageText.prefix(30))
                    }
                }
                .padding()
            Text(String(messageText.count))
        }
    }
}

ユーザーに安全なパスワードを選ぶように依頼してください

ユーザーの入力したパスワードが最低でも1つの大文字、1つの記号、数字を含んでいるかどうか、および若干長すぎないかどうか、チェックすることができます。

import SwiftUI
import Combine

struct ContentView: View {
    
    @State var messageText: String = ""
    
    @State var hasCapitalLetter: Bool = false
    @State var hasSymbol: Bool = false
    @State var lengthExceeds16: Bool = false
    
    var body: some View {
        
        Form {
            TextField("メッセージ", text: $messageText)
                .onReceive(Just(messageText)) { _ in
                    self.lengthExceeds16 = (messageText.count > 16)
                    // 大文字
                    let capitalLetterExpression  = ".*[A-Z]+.*"
                    let capitalLetterCondition = NSPredicate(format:"SELF MATCHES %@", capitalLetterExpression)
                    self.hasCapitalLetter = capitalLetterCondition.evaluate(with: messageText)
                    // 数字: ".*[0-9]+.*"
                    // 符号
                    let symbolExpression  = ".*[!&^%$#@()/]+.*"
                    let symbolCondition = NSPredicate(format:"SELF MATCHES %@", symbolExpression)
                    self.hasSymbol = symbolCondition.evaluate(with: messageText)
                }
                .padding()
            // ユーザーによるパスワード入力をご希望の場合は、`SecureField` をご利用下さい。
            Text(String(messageText.count))
                .keyboardType(.asciiCapable)
                .autocapitalization(.none)
                .disableAutocorrection(true)
            // パスワード 条件
            PasswordConditionDisplay(isConditionMet: $hasCapitalLetter, conditionName: "大文字")
            PasswordConditionDisplay(isConditionMet: $hasSymbol, conditionName: "符号")
            PasswordConditionDisplay(isConditionMet: $lengthExceeds16, conditionName: "パスワードは16文字を越える必要があります")
        }
        
    }
    
}

struct PasswordConditionDisplay: View {
    @Binding var isConditionMet: Bool
    var conditionName: String
    var body: some View {
        HStack {
            Image(systemName: isConditionMet ? "circle.fill" : "xmark")
                .padding(.horizontal, 5)
            Text(conditionName)
        }
    }
}

:relaxed: Twitter @MszPro

:sunny: 私の公開されているQiita記事のリストをカテゴリー別にご覧いただけます。

14
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?