当tableview单元格变得不可见时如何获取UITextField(UITableViewCell的子视图)文本值

Posted

技术标签:

【中文标题】当tableview单元格变得不可见时如何获取UITextField(UITableViewCell的子视图)文本值【英文标题】:How to get UITextField (subview to UITableViewCell) text value when tableview cell became invisible 【发布时间】: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 【参考方案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)获取。

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

【讨论】:

以上是关于当tableview单元格变得不可见时如何获取UITextField(UITableViewCell的子视图)文本值的主要内容,如果未能解决你的问题,请参考以下文章

当单元格的高度不同时,如何在表格视图中获取所有单元格的高度?

如何删除不可见的 tableview 单元格的下载图像。在ios中

在单元格中单击时,tableView:indexPathForCell 返回 nil

如何将单元格的值从 TableView 获取到另一个视图

在 tableview 单元格中将图像设置为 UIImageView 会使滚动和旋转变慢

进入视图时如何禁用 TableView 单元格图像下载