在输入另一个单元格后,如何在单元格中启用禁用的文本字段?

How do I enable a disabled textfield in a cell after typing in another one?

我有一个包含三个单元格的 table 视图控制器,每个单元格都有一个用户定义的文本字段: -国家 -状态(禁用) -城市(已禁用)

如何在用户输入 "Country" 后启用 "State" 文本字段?

主要问题是我正在使用一个名为 "Field" 的模型,它有一个名为 "depends" 的 属性,它显示了另一个字段的 ID,该字段不能是空。

我的自定义 table 视图单元格有一个 属性 "Field"。

如果我使用 "textfieldDidBeginEditing()",我只能访问单元格内的文本字段,而不能访问 "Field" 属性。

我所有的单元格都是动态创建的。

项目在Objective-C。

很简单,这是你的步骤

  1. 将 textfield.delegate 设置为您的 UIViewController
  2. 实现 UITextFieldDelegate 方法- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
  3. 如果需要检查文本长度
  4. 使用以下代码获取您想要启用的下一个单元格:

    UITableViewCell *thisCell = [textView superCell];
    NSIndexPath *thisIndexPath = [tableView indexPathForCell:thisCell];
    NSIndexPath *nextIndexPath = [NSIndexPath indexPathForRow:thisIndexPath.row inSection:thisIndexPath.section];
    UITableViewCell *nextCell = [tableView cellForRowAtIndexPath: nextIndexPath];
    
  5. nextCell

  6. 中的文本字段调用 becomeFirstResponder

您需要使用以下方法创建一个 UIView 类别,上面的代码才能正常工作

- (UITableViewCell *)superCell {
    UIView *cell = self;
    do {
        cell = cell.superview;
    } while( ![cell isKindOfClass:[UITableViewCell class]] && cell != nil           );

    return (UITableViewCell *)cell;
}

有一个按钮:

-(IBAction) continueButton: (UIButton*) sender{

    //check if the state textfield is not empty in order to proceed
    if(![self.stateTextfield.text isEqualToString: @""]){
        self.cityTextfield.enabled = YES;
    }
}

四处逛逛很简单,但不是很干净。

更新

  1. 使用普通的视图控制器。
  2. 将容器视图拖到视图控制器中,以允许捕获数据的 table 视图的大小。
  3. 删除自动生成的View Controller,拖一个Table View Controller到storyboard上,嵌入到Container View中(ctrl + drag and select embed in选项)
  4. 将此 table 视图设置为静态。
  5. 拖一个TableView(notTableViewController)到ViewController.
  6. Ctrl + 从 TableView 拖动到 View Controller 图标并设置数据源和委托。这将允许数据加载到 table 视图。

现在这应该可以解决加载数据的任何问题,因为数据将加载到动态 table 视图中,而静态 table 视图将保持不变(如果这对您来说是一个可行的选择) .这样您就可以将文本字段连接到视图控制器并访问它们的属性。

如果您需要任何帮助或者这不是一个好的解决方案,请告诉我。

使用 UITextFieldDelegate 的 textFielShouldBeginEditing 方法

声明

SWIFT

optional func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool

OBJECTIVE-C

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField

示例-

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{
       //do state button enabled task here
  }

简短:

对于像您这样的简短列表(table 视图可以将所有单元格放在屏幕上),保留对所有三个字段的引用就足够了:

// Your model
@interface AddressStorageModel : NSObject
@property (strong, nonatomic) NSString* country;
@property (strong, nonatomic) NSString* state;
@property (strong, nonatomic) NSString* city;
@end
// Your cell
@interface FieldTableCell : UITableViewCell
@property (readonly, nonatomic) UITextField* textField;
@end
// Your view controller implementation
@implementation ViewController
{
    __weak UITextField* _countryField;
    __weak UITextField* _stateField;
    __weak UITextField* _cityField;
    AddressStorageModel* _addressStorage;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 3;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    FieldTableCell *cell = (FieldTableCell*)[tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
    cell.textField.delegate = self;
    switch (indexPath.row) {
        case 0: // Country
            _countryField = cell.textField;
            break;
        case 1: // State
            _stateField = cell.textField;
            break;
        case 2: // City
            _cityField = cell.textField;
            break;
    }

    return cell;
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];
    return YES;
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    // Validate somehow and move cursor to next field:
    if (textField.text.length) {
        UITextField* nextTextField = [self p_textFieldNextTo:textField];
        [nextTextField setEnabled:YES];
        [nextTextField becomeFirstResponder];
    }
}

- (UITextField *)p_textFieldNextTo:(UITextField *)textField
{
    if (textField == _countryField)
        return _stateField;
    else if (textField == _stateField)
        return _cityField;
    return _countryField;
}

- (void)completeButtonAction:(id)sender
{
    _addressStorage.country = _countryField.text;
    _addressStorage.state = _stateField.text;
    _addressStorage.city = _cityField.text;
}

更复杂...但更简单以便将来支持

但是如果您打算增加字段的数量,您应该以这种方式实现您的代码:

// Your model
@interface AddressField : NSObject
@property (strong, nonatomic) NSString* title;
@property (strong, nonatomic) NSString* value;
@property (strong, nonatomic) AddressField* dependency;
@property (strong, nonatomic) NSIndexPath* indexPath;
@end

// Your cell

@protocol FieldTableCellDelegate <NSObject>
@required
- (void)fieldCellDidEndEditing:(FieldTableCell*)cell;
@end

@interface FieldTableCell : UITableViewCell <UITextFieldDelegate>
@property (readonly, weak, nonatomic) AddressField* addressField;
@property (weak, nonatomic) id<FieldTableCellDelegate> delegate;
- (void)configureForField:(AddressField *)field;
- (void)startEditing;
@end

@implementation ViewController
{
    NSArray * _fields; // I left to your discretion how to create fields and assign dependencies
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return _fields.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    FieldTableCell *cell = (FieldTableCell*)[tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
    cell.delegate = self;

    AddressField * field = _fields[indexPath.row];
    field.indexPath = indexPath;
    [cell configureForField:field];

    return cell;
}

- (void)fieldCellDidEndEditing:(FieldTableCell *)cell
{
    typeof(self) __weak weakSelf = self;
    [UIView animateWithDuration:0.25
                     animations:^{
                         [weakSelf.tableView scrollToRowAtIndexPath:cell.addressField.dependency.indexPath
                                                   atScrollPosition:UITableViewScrollPositionMiddle
                                                           animated:NO];
                     }
                     completion:^(BOOL finished) {
                         FieldTableCell* nextCell = (FieldTableCell*)[weakSelf.tableView cellForRowAtIndexPath:cell.addressField.dependency.indexPath];
                         [nextCell startEditing];
                     }];
}

@end

@implementation FieldTableCell
{
    UITextField* _inputField;
}

- (void)configureForField:(AddressField *)field
{
    _addressField = field;
    _inputField.text = field.value;
    _inputField.placeholder = field.title;
    // do all other configurations...
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    if (textField.text.length > 0) {
        _addressField.value = textField.text;
        [_delegate fieldCellDidEndEditing:self];
    }
}

- (void)startEditing
{
    [_inputField becomeFirstResponder];
}

@end