【问题标题】:Clear all UITextField changes in a UITableView with a UIButton使用 UIButton 清除 UITableView 中的所有 UITextField 更改
【发布时间】:2011-03-28 15:34:42
【问题描述】:

我有一个包含十几行的 UITableView,每行都包含一个 UITextField。 默认情况下,如果用户之前没有编辑过文本字段,则 UITextField 包含一个占位符值“添加值”:

UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(158, 6, 148, 24)];

NSString *strReplacement = [valueArray objectAtIndex:indexPath.row];

if (([strReplacement length] != 0) {
    textField.text = strReplacement;
} else {
    textField.placeholder = @"Add Value";
}

textField.delegate = self;
[cell addSubview:textField];
[textField release];

到目前为止一切顺利。

我还在 UITableView 的页脚添加了一个 UIButton。 我想要的是在用户单击 UIButton 时清除所有已编辑的值并刷新 UITableView 中的所有 UITextField。

我可以轻松地从 valueArray 中删除所有对象,但我不知道如何刷新所有 UITableView 单元格以反映更改。

感谢任何帮助。 lq

【问题讨论】:

    标签: iphone xcode uitableview uitextfield


    【解决方案1】:

    我相信你正在寻找的是

    [tableView reloadData];
    

    【讨论】:

    • 当我按下 UIButton 时,我会清除 valueArray 中的值(并验证这些值已被清除),但替换值仍在 reloadData 后填充 UITextFields。
    • 这很奇怪。您可能想在cellForRowAtIndexPath: 方法中放置一个断点,然后查看reloadData 之后的valueArray 的内容。
    • - (IBAction)clearReplacements:(id)sender { [self.valueArray removeAllObjects]; [myTableView 重载数据];不重新加载表。使用断点代码只是在 reloadData 之后停止。
    • 好的,当它停在tableView:cellForRowAtIndexPath:内时,你能检查valueArray的内容吗?您在 clear 方法中使用 self.valueArray,但在填充表格视图时只是 valueArray(直接 ivar),您确定它们是一样的吗? (也许您将该属性声明为 copy 或类似的名称?)
    • GDB 在方法 clearReplacements 结束时在 Step 后停止。它不会重新加载表,实际上什么也没发生。
    【解决方案2】:

    您的解决方案感觉很奇怪。 Filipe 认为正确的做法是使用[wordsTableView reloadData],这将导致为每个可见单元格调用tableView:cellForRowAtIndexPath:。当您滚动表格时也会调用该方法,因此如果 reloadData 不起作用,您可能还会遇到数据在更改和滚动时无法正确更新的错误。在您的 clearValues 方法中,您通过调用 tableView:cellForRowAtIndexPath: 来做同样的事情。

    我认为真正的问题在于您的tableView:cellForRowAtIndexPath: 实现。该方法通常有 2 个部分。首先,您创建或回收一个单元格以获取类似以下内容的引用:

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
    }
    

    在 if 语句中通常是您应该向单元格添加子视图的唯一地方。如果dequeueReusableCellWithIdentifier: 返回一个单元格,它应该已经有子视图。

    然后,在 if 语句之后,您填充或更新子视图的内容。您的原始代码的问题在于它正在填充文本字段并将其添加为子视图,假设单元格中还没有文本字段。所以你的tableView:cellForRowAtIndexPath: 应该看起来更像这样:

    int textFieldTag = 100;
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
        UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(158, 6, 148, 24)];
        [textField setTag:textFieldTag];
        [textField setDelegate:self];
        [cell addSubview:textField];
        [textField release];
    }
    
    UITextField *textField = [cell viewWithTag:textFieldTag];
    NSString *strReplacement = [valueArray objectAtIndex:indexPath.row];
    
    if (([strReplacement length] != 0) {
        textField.text = strReplacement;
    } else {
        textField.placeholder = @"Add Value";
    }
    

    看起来您可能正在将 textField 的标记值设置为行号,大概这样您就可以在 UITextFieldDelegate 中使用它。这也可能导致错误,就像第 1 行的单元格被 dequeueReusableCellWithIdentifier: 回收并变成第 12 行一样,它将具有意外的标记值。即使现在没有发生,这也是一个等待发生的错误,并且很难排除故障。

    【讨论】:

      【解决方案3】:

      Filipe 的解决方案也应该有效,但是,应尽可能避免调用 reloadData,因为调用此方法会产生很高的性能开销。

      您需要某个类同时引用 UIButton 实例以及屏幕上/表格中的所有 UITextField 实例。听起来是您的 UITableView 控制器子类的完美工作!

      在上面的代码中,为什么不将您创建的每个 UITextField 添加到 UITableView 中的文本字段 NSArray em>控制器?然后当用户按下 UIButton 时,动作可以调用控制器类中的某个方法,该方法会循环遍历 NSArray 中的所有 UITextField 元素将每个实例的text 属性设置为@""

      警告:如果您重复使用单元格,那么您可能必须确保控制器的 UITextFieldsNSArray 正在正确更新。

      【讨论】:

      • 我正在为每个 UITextField 元素使用标签属性,但我不清楚如何在单独的方法中解决它们?
      【解决方案4】:

      经过几个小时的反复试验,我想出了这个解决方案。 UIButton "Clear All" 调用如下方法:

      - (IBAction)clearValues:(id)sender {
      
          // count the number of values in the array (this is the same as the number of rows in the table)
          int count = [valueArray count];
      
          // remove all values from the array (deletes any user added values):
          [self.valueArray removeAllObjects];
      
          UITableViewCell *cell;
          UITextField *textField;
      
          // loop through each row in the table and put nil in each UITextField:
          for (NSUInteger i = 0; i < count; ++i) {
      
              NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0];
              cell = [self.wordsTableView cellForRowAtIndexPath:indexPath];
      
              // NOTE: Make sure none of your tags are set to 0 since all non-tagged objects are zero.
              // In table construction, your textFieldTags should be: textField.tag=indexPath.row+1;
      
              textField = (UITextField*)[cell viewWithTag:i+1];
              textField.text = nil;
      
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 2013-09-12
        • 2017-10-15
        • 1970-01-01
        • 2012-11-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-27
        • 1970-01-01
        • 2014-04-05
        相关资源
        最近更新 更多