维护提及的UITextField“文本”字段

问题描述:

问题:维护提及的UITextField“文本”字段

我试图创建一个自定义UITextField类“UIValidatedTextField”,它允许一个设置一定的规则来输入是否有效。例如,你可以设置一个正则表达式参数,以确保输入是一个特定的格式,即密码,电子邮件地址等...

另一个能力是指定和设置引用另一个UITextField的参数和确保输入与来自其他UITextField的输入匹配。

我在这里遇到的问题是我将此引用设置为另一个UITextField。然而,当我访问它的“文本”字段时,我发现即使在输入内容时,文本字段中也没有任何内容。下面

我已经提供了相关代码:

#import "UIRegisterViewController.h" 
#import "UIRegisterViewCell.h" 
#import "UIValidatedTextField.h" 
#import "NSConstants.h" 

@interface UIRegisterViewController() 


@end 

@implementation UIRegisterViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    _tableView.delegate = self; 
    _tableView.dataSource = self; 
    _tableItems = @[@"name", @"email", @"netId", @"username", @"password", @"confirmPassword"]; 

} 

- (void)didReceiveMemoryWarning { 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

#pragma mark - Table view data source 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    return [_tableItems count]; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ 
    NSString *cellIdentifier = [_tableItems objectAtIndex:indexPath.row]; 
    UIRegisterViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath]; 


    if ([cellIdentifier isEqualToString:@"email"]) { 
     [cell.textField setRegex:VALID_DUKE_EMAIL_REGEX]; 

    } else if ([cellIdentifier isEqualToString:@"netId"]) { 
     //Validation? 

    } else if ([cellIdentifier isEqualToString:@"username"]) { 
     //Validation? 

    //THIS IS THE CELL THAT I WANT TO COMPARE INPUT TO 
    } else if ([cellIdentifier isEqualToString:@"password"]) { 
     [cell.textField setRegex:VALID_PASSWORD_REGEX]; 

    //SETTING THE TEXT FIELD IN QUESTION HERE... 
    } else if ([cellIdentifier isEqualToString:@"confirmPassword"]) { 
     [cell.textField setRegex:VALID_PASSWORD_REGEX]; 
     NSIndexPath *index = [NSIndexPath indexPathForRow:4 inSection:0]; 
     UIRegisterViewCell *confirm =(UIRegisterViewCell *)[self tableView:_tableView cellForRowAtIndexPath:index]; 
     [cell.textField setConfirm:confirm.textField]; 
    } 

    cell.textField.delegate = self; 
    return cell; 
} 

#pragma mark - Text Field Delegate 
- (BOOL)textFieldShouldReturn:(UITextField *)textField { 
    [textField resignFirstResponder]; 
    return YES; 
} 


@end 

注意,文本框是UIValidatedTextFields - 下面提供的自定义类:

#import "UIValidatedTextField.h" 
#import "NSArgumentValidator.h" 

@implementation UIValidatedTextField 

- (id) initWithCoder:(NSCoder *)aDecoder { 
    self = [super initWithCoder:aDecoder]; 
    if (self) { 
     [self initialize]; 
    } 
    return self; 
} 

- (id)initialize { 
    if (self) { 
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldDidChange:) 
       name:UITextFieldTextDidChangeNotification object:self]; 
     [self validate]; //Validate in case editing began before observer was set. 
    } 
    return self; 
} 

- (void) setOptional:(BOOL)isOptional { 
    _isOptional = isOptional; 
} 

- (BOOL) isOptional { 
    return _isOptional; 
} 

- (void) setRegex:(NSString *)regex { 
    _regex = regex; 
} 

//SET THE TEXT FIELD TO COMPARE INPUT AGAINST HERE. 
- (void) setConfirm:(UITextField *)confirm { 
    _confirm = confirm; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textFieldDidChange:) 
      name:UITextFieldTextDidChangeNotification object:_confirm]; 
    [self validate]; //Validate in case editing on confirm began before observer was set. 
} 

- (void) setQuery:(NSString *)query { 
    _query = query; 
} 

- (void) textFieldDidChange:(NSNotification *)notification { 
    NSLog(@"UPDATE"); 
    _isValid = [self validate]; 
    [self showInputValidation]; 
} 

- (BOOL) validateRegex { 
    if (_regex.length == 0) { 
     return true; 
    } 
    return [NSArgumentValidator isValid:self.text withRegex:_regex]; 
} 

- (BOOL) validateConfirm { 
    // NSLog(@"%@ : %@", [_confirm text], self.text); 
    if (_confirm == NULL) { 
     //NSLog(@"IS NULL"); 
     return true; 
    } 
    return [self.text isEqualToString:_confirm.text]; 
} 

- (BOOL) validateQuery { 
    return true; 
} 

- (BOOL) validate { 
    _isValid = (self.text == 0 && _isOptional) || ((self.text != 0) && [self validateRegex] && [self validateConfirm] && [self validateQuery]); 
    return _isValid; 
} 

//IF ANYONE HAS A SOLUTION AS TO HOW TO MAKE CHANGING BORDER COLOR CHANGE THE COLOR ALONG THE ROUNDED BORDER THAT IS PRESENT AS OPPOSED TO A RECTANGULAR BORDER LET ME KNOW. 
- (void) showInputValidation { 
    self.layer.borderWidth = 1.0; 
    if (self.text.length == 0) { 
     self.layer.borderColor = [[UIColor blackColor] CGColor]; 
    } else if (_isValid) { 
     self.layer.borderColor = [[UIColor greenColor] CGColor]; 
    } else { 
     self.layer.borderColor = [[UIColor redColor] CGColor]; 
    } 
} 
- (void) finalize { 
    [super finalize]; 
    [[NSNotificationCenter defaultCenter] removeObserver:self 
      name:UITextFieldTextDidChangeNotification object:self]; 

    if (_confirm != NULL) { 
     [[NSNotificationCenter defaultCenter] removeObserver:self 
       name:UITextFieldTextDidChangeNotification object:_confirm]; 
    } 
} 

@end 

感谢您的帮助!

此代码中的一个明显错误是,即使所有单元格都在重用相同的单元格对象,您仍然在cellForRowAtIndexPath:中设置正则表达式。 cellForRowAtIndexPath:应仅用于设置单元格内容,如文本和颜色。相反,请创建一个IBOutlet来验证文本字段并在viewDidLoad中添加它们的正则表达式。更好的办法是,完全取消自定义子类,并在编辑完成后,只要有一个相关文本字段触发事件就运行正则表达式验证。

+0

每个出队的单元都不同,并且具有不同的标识符。我确信我可以用这种方式修复它,尽管非常混乱,但我也想明白为什么这种方式无法实现。 – nothingness 2014-09-05 04:20:00

+0

这是因为可重复使用的单元格像橡皮图章一样用于绘制单元格,而不是用于处理单元格后面的业务逻辑。我不确定,但是我的猜测是,当你在一次调用dequeue中设置正则表达式时,会在下一次出列调用时被破坏,或者被检查的文本被破坏。 – NRitH 2014-09-06 00:05:16

+0

我想我现在看到了,所以基本上当您调用该方法时,它将在指定索引处重新创建单元格,而不是检索正在显示的实际单元格 - 或者我误解了?无论如何检索实际的细胞? – nothingness 2014-09-06 05:41:43