使用 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
属性设置为@""
。
警告:如果您重复使用单元格,那么您可能必须确保控制器的 UITextFields 的 NSArray 正在正确更新。
【讨论】:
我正在为每个 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 添加到简单的电子表格示例