Subscribed unsubscribe Subscribe Subscribe

iosのフォームバリデーションみたいなの

tableViewで作ってたので、その例で。

tableViewControllerをtextfieldのdelegateにしちゃうと、「これは何文字」とか、「これは必須」とかどうこうとか面倒なことになるなーと思って、そういう形にはしなかった。

一個のcellに一個のフィールドがあることが多いし、UITableViewCellをサブクラス化して、バリデーションすることにした。バリデーションメッセージを出すのもCellだけでやりたかったけど、cellからはみ出る吹き出しみたいにしたかったので、それはtableViewControllerにさせてる。

@protocol TQValidatableFieldDelegate

- (void)cell:(UITableViewCell *)cell didResolveValidationErrorWithErrorView:(UIView *)errorView;
- (void)cell:(UITableViewCell *)cell didOccurValidationErrorWithErrorView:(UIView *)errorView;

@end

// ---------- Custom Cell ----------

- (BOOL)validate
{
    if ([self TQ_validate]) {
        [self.delegate field:self didResolveValidationErrorWithErrorView:_validationErrorView];
    } else {
        [self.delegate field:self didOccurValidationErrorWithErrorView:_validationErrorView];
    }

    return isValid;
}

- (BOOL)TQ_validate
{
    if (_inputField.text.length == 0) {
      _validationErrorView.message = @"入力してください。";
      return NO;
    }

    if (_inputField.text.length <= _minLength) {
      _validationErrorView.message = [NSString stringWithFormat:@"%d文字以上で入力してください。", _minLength + 1];
      return NO;
    }

    if (_inputField.text.length > _maxLength) {
      _validationErrorView.message = [NSString stringWithFormat:@"%d文字以内で入力してください。", _maxLength];
      return NO;
    }

    _validationErrorView.message = @"";
    return return YES;
}

// ---------- TableViewController ----------
- (void)cell:(UITableViewCell *)cell didReceiveValidationErrorWithErrorView:(UIView *)errorView
{
    if (![errorView isDescendantOfView:self.tableView]) {
        [self.tableView addSubview:errorView];
        [self.tableView bringSubviewToFront:errorView];
    }
}

- (void)cell:(UITableViewCell *)cell didRemoveValidationErrorWithErrorView:(UIView *)errorView
{
    if ([errorView isDescendantOfView:self.tableView]) {
        [errorView removeFromSuperview];
    }
}

textFieldのdelegateになってるcellが変更があったりした適当なタイミングでvalidateするのと、フォームをsubmitする時のtableViewControllerが全部のcellに対してvalidateするみたいな感じにしてる。その辺は省略。

best practiceとか大体こうやってるよみたいなのは知らない。