1

問題:維護提及的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 

感謝您的幫助!

回答

0

此代碼中的一個明顯錯誤是,即使所有單元格都在重用相同的單元格對象,您仍然在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