使用 UIButton 清除 UITableView 中的所有 UITextField 更改

Posted

技术标签:

【中文标题】使用 UIButton 清除 UITableView 中的所有 UITextField 更改【英文标题】:Clear all UITextField changes in a UITableView with a UIButton 【发布时间】: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

【问题讨论】:

【参考方案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;

    


【讨论】:

以上是关于使用 UIButton 清除 UITableView 中的所有 UITextField 更改的主要内容,如果未能解决你的问题,请参考以下文章

RxSwift 如何将“清除所有”UIButton 添加到简单的电子表格示例

在 Xamarin.iOS 中使用 UITableViewCell 展开 Segue

使用清晰的背景颜色使 UIButton 内容完全可点击

如何允许自动调整UIButton的大小以满足间距约束

iOS清除缓存

iOS之清除缓存