6
6

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 5 years have passed since last update.

NSTextFieldの入力値の検証

Posted at

ソース: https://github.com/Nunocky/TextFieldValidation

#やりたいこと
ネットワーク設定でIPアドレスを入力させたいとか 140文字以内のテキストを入力させたいとかいうときに、それらの条件を満たさないことをどうやってユーザーに通知したら良いか?

ちなみにOSXのネットワーク設定のIPアドレス設定ではこんなアラートが出てテキストが "0.0.0.0"になる。

fig2.png

##その1 NSTextFieldのnotificationを利用する
TextFieldValidationでは、NSTextFiledのdelegateに AppDelegateを指定している。
そしてAppDelegateに controlTextDidEndEditing: メソッドを実装し、その中でどのTextFieldから来た通知なのかを判定、適切な評価器を呼んで評価する。
この方法を使えば、NSTextFieldの中でEnterを押したりTabキーなんかでフォーカスを他のところに移動した時に評価が行われる。

-(void)controlTextDidEndEditing:(NSNotification *)notification
{
    NSTextField *tf = [notification object];
    NSString *identifier = [tf identifier];

    if ([identifier isEqualToString:@"ipaddress"]) {
        IPAddressTextValidator *validator = [[IPAddressTextValidator alloc] init];
        if (![validator validate:tf.stringValue]) {
            NSRunAlertPanel(@"error",
                            @"invalid format",
                            @"close",
                            nil,
                            nil);
        }
    }
.
.
.

##その2 文字列プロパティにbindする方法
TextFieldValidation2は入力をリアルタイムに見る方法。
AppDelegateに NSStringのプロパティを用意、NSTextFieldのvalueプロパティにそれぞれbindする。その際、オプション「Continuously Updates Value」を有効にする。これで文字を入力するたびにプロパティの setterが呼ばれるようになる。

TextFieldValidation2.png

あとはプロパティの setterの中でテキスト評価器による判定を行えば良い。不正だったら背景を赤くするとか、ツールチップに正しい値のサンプルを表示させるとか。

AppDelegate.m
-(void)setText0:(NSString *)text0
{
    if ([_text0 isEqualToString:text0])
        return;
    _text0 = [text0 copy];
    
    IPAddressTextValidator *validator = [[IPAddressTextValidator alloc] init];
    if (![validator validate:_text0]) {
        [_textField0 setBackgroundColor:[NSColor redColor]];
    }
    else {
        [_textField0 setBackgroundColor:[NSColor whiteColor]];
    }
}

###困っていること
TextFieldValidation2では不正な入力の際にTextFieldの背景を赤くするつもりなのだけど、編集中にsetBackgroundColorを行ってもエリアの上の部分がちょっと赤くなるだけで全体が赤くならない問題が。フォーカスを外すと全体が赤くなる。これどうすれば直せるんだろう。

#テキスト評価器について
サンプルではIPAddressTextValidatorと LessThan30TextValidatorの2つを作ってみた。この辺何か汎用的なクラスがあるんじゃないかって気がする。けどStackOverflowみても特にそれらしいクラスはないようだし、みんなどうしてるんだろう。

6
6
1

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
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?