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

时间:2014-04-08 06:52:00

标签: ios objective-c uitableview uitextfield

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

cellForRowAtIndexPath对于不可见的单元格返回nil,在我向下滚动到我的tableview的buttom之后然后点击Add按钮,第一行几行' 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

4 个答案:

答案 0 :(得分:3)

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

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

  • 将细胞作为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];
    }

答案 1 :(得分:1)

这不是问题。每当创建新单元格时,单元格都会出列并重新使用。当在顶部滚动tableview时,它们变为null,并且使用相同的标识符创建新单元格。

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

- (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;
}

答案 2 :(得分:0)

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

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

无论如何,你试图避免从表视图控制器调用cellForRowAtIndexPath :.

答案 3 :(得分:0)

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

您最初可能正在使用arra,y加载tablecell。如果是这样,请使用该数组创建您提到的模型类对象而不是tablecells。