【问题标题】:How to get UITextField (subview to UITableViewCell) text value when tableview cell became invisible当tableview单元格变得不可见时如何获取UITextField(UITableViewCell的子视图)文本值
【发布时间】:2014-04-08 06:51:59
【问题描述】:

我创建了一个自定义UITableViewCell 类,该类将UITextfield 嵌入到每个单元格中,在addItemTableViewController 中,我想在所有UITextField-embededd 单元格中获取文本值并创建一个新模型对象,但我遇到问题:

cellForRowAtIndexPath 为不可见的单元格返回 nil,在我向下滚动到我的 tableview 的底部然后点击添加按钮后,前几行的 textField 文本值变为 null。

无论如何我可以解决这个问题吗?我已经在谷歌上搜索了几个小时,但仍然没有找到答案。

这是我的 addItemTableViewController 代码:

    - (IBAction)doneAdd:(UIBarButtonItem *)sender {
        [self.delegate addItem:[self newItem]];
    }

    - (NSMutableArray *)newItem
    {
        NSMutableArray *newItem = [[NSMutableArray alloc] init];

        for (int i = 0; i < [_appDelegate.title count]; i ++) {
            NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
            UPFEditableUITableViewCell *cell = (UPFEditableUITableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath];
            NSLog(@"%@", cell.editField.text);
            //[newItem addObject:cell.editField.text]; //this does not work as null cannot be added into a array
        }
        NSLog(@"%@", newItem);
        return newItem;
    }

这是我的自定义 UITableViewCell 类实现

    #import "UPFEditableUITableViewCell.h"

    @implementation UPFEditableUITableViewCell

    - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
    {
        self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
        if (self) {
            self.editField = [[UITextField alloc] initWithFrame:CGRectZero];
            [self.contentView addSubview:self.editField];
        }
        return self;
    }

    - (void)layoutSubviews
    {
        if ([self.detailTextLabel.text length] == 0) {
            self.detailTextLabel.text = @" ";
        }

        [super layoutSubviews];

        // place the edit field in the same place as the detail text field, give max width
        self.editField.frame = CGRectMake(self.detailTextLabel.frame.origin.x, self.detailTextLabel.frame.origin.y, self.contentView.frame.size.width-self.detailTextLabel.frame.origin.x, self.detailTextLabel.frame.size.height);
    }

    - (void)showEditingField:(BOOL)show
    {
        self.detailTextLabel.hidden = YES;
        self.editField.text = self.detailTextLabel.text;
    }


    @end

【问题讨论】:

  • 你不能通过 Cell 访问文本字段,在 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;您应该相应地为每个 textField 提供标签,然后您就可以轻松获取 textFields

标签: ios objective-c uitableview uitextfield


【解决方案1】:

我认为犯了一个根本性的错误,让我的观点与模型层对话,吸取了什么教训......

无论如何,我设法找到了一个解决方案,简而言之,这就是我所做的:

  • 将单元格作为 UITextField 的代表
  • 实现了textFieldDidChange,捕捉textField的变化,一旦有变化,将变化的内容提交给模型

这是代码:

在 cellForRowAtIndex 中:

    [cell.editField addTarget:self action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
     cell.editField.delegate = self;

这是 textFieldDidChange 的代码:

    - (void)textFieldDidChange :(UITextField *)theTextField
    {
        NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
        [self.item removeObjectAtIndex:indexPath.row];
        [self.item insertObject:theTextField.text atIndex:indexPath.row];
    }

【讨论】:

    【解决方案2】:

    这不是问题。每当创建新单元格时,单元格就会出列并重用。因此,在滚动顶部的表格视图时,它们会变为空,并且新单元格会使用相同的标识符创建。

    对于您的问题,您需要将文本字段的值存储到字典中。为此,您需要在将单元格出列时保存它。

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    static NSString *cellReuseIdentifier = @"cellIdentifier";
    
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellReuseIdentifier];
    
        if (!cell) {
                   cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellReuseIdentifier];
    
        }else{
            NSLog(@"text is %@",cell.textLabel.text);
    
    for (UIView *v in cell.contentView.subviews) {
            if ([v isKindOfClass:[UITextField class]]) {
                UITextField *textField = (UITextField *)v;
            [myDictionary setObject:textField.text forKey:indexPath]; // declare myDictionary in the interface first.This will also prevent the values from duplicating
      NSLog(@"%@",myDictionary);
            }
          }
        }
    return cell;
    }
    

    【讨论】:

      【解决方案3】:

      要从UITextField 获取价值,您可以在 ViewController 上设置委托。然后你应该实现textField:shouldChangeCharactersInRange:replacementString:,你可以在其中更新 NSString 值。

      第二种解决方案可能是保持对NSMutableArray 中每个单元格的引用。

      无论如何,您都尽量避免从表视图控制器调用 cellForRowAtIndexPath:。

      【讨论】:

        【解决方案4】:

        您应该始终尝试将数据保存在模型类中,并使用这些模型类实例的数组来加载表。这样您之后就不需要 tableCells 来获取数据了。数据总是从模型中获取,而不是从 UI(本例中为 TableCells)获取。

        您最初可能使用数组加载表格单元。如果是这样,请使用该数组来创建您提到的模型类对象而不是表格单元。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-03-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多