我在每一行都有按钮,我想显示UIActivityIndicatorView来代替我按下以显示加载过程的按钮。所以我通过更改按钮属性使其看起来像这样的微调器来完成它:
[search_btn_outlet setTitle:@"" forState:UIControlStateNormal];
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[spinner startAnimating];
spinner.frame = search_btn_outlet.bounds;
[search_btn_outlet addSubview:spinner];
search_btn_outlet.enabled = NO;
现在我想用新数据重新加载我的表。但是方法[tableview reloadData]调用相同的cellForRowAtIndexPath,它重用以前被破坏的单元格。我可以把这样的代码放在那里:
[boy.search_btn_outlet setTitle:@"Button name" forState:UIControlStateNormal];
boy.search_btn_outlet.enabled = YES;
但我想知道我是否可以立即将我的表重置为storyboard cell prototype中指定的内容?如果我不能,如何处理那个微调器,我在按下按钮时添加了什么?
编辑:我很困惑,因为我来自Android,在相同的情况下,单元格在消失后返回默认原型。显然在iOS开发人员对prepareForReuse负责。 (Thx Abizern)。
我正在做的是在行对象中保持指向行按钮和行状态“isLoading”的指针。在cellForTowAtIndexPath中,我将按钮设置为正常或加载动画。要删除微调器,我也持有它的参考。
其他方法是仅在isLoading为true时才更改行视图。按下时我的刷新按钮将循环播放数组中的所有行项,并将其视图恢复正常。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = @"boy_cell";
BoyItem *boy = [self.boys_array objectAtIndex:indexPath.row];
BoyCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[BoyCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.delegate = self; //for search button callback
cell.cellIndex = indexPath.row;
/* save pointer to the button to change it when button is pressed */
boy.search_btn_outlet = cell.search_btn_outlet;
if(boy.isLoading){
[self setRowLoading:boy];
}
else{
[self setRowNormal:boy];
}
[cell.name_lbl setText:boy.name];
[cell.time_lbl setText:boy.time];
}
return cell;
}
-(void)setRowLoading:(BoyItem*)boy{
[boy.search_btn_outlet setTitle:@"" forState:UIControlStateNormal];
UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
[spinner setColor:[UIColor purpleColor]];
[spinner startAnimating];
spinner.frame = boy.search_btn_outlet.bounds;
boy.spinner = spinner;
[boy.search_btn_outlet addSubview:spinner];
boy.search_btn_outlet.enabled = NO;
}
-(void)setRowNormal:(BoyItem*)boy{
[boy.search_btn_outlet setTitle:@"Search" forState:UIControlStateNormal];
boy.search_btn_outlet.enabled = YES;
[boy.spinner removeFromSuperview];
}
- (void)didClickOnCellAtIndex:(NSInteger)cellIndex withData:(id)data
{
BoyItem *boy = [self.boys_array objectAtIndex:cellIndex];
if(boy!=nil){
boy.isLoading = true;
[self setRowLoading:boy];
}
}
我并非100%确定这是一种正确的方法。但如果它关闭了,我希望它对某人有帮助。
Edit2 :然后我发现除了重新加载整个表之外,还有至少两种方法可以刷新单元格属性。当您更改单元格高度时,它会带来动画效果。 一种方法是将更改放在这些方法之内或之前:
[tableview beginUpdates];
//boy_cell.backgroundColor =row_color;
[tableview endUpdates];
它为每一行调用heightForRowAtIndexPath,因此您希望将新高度放入属于每个单元格的对象中。请注意,您需要检查此行是否可见。否则,您可能会更改该行的颜色,该行已被重复用于表格的其他单元格。
您还可以重新加载表格的特定行。将为一行调用cellForRowAtIndexPath:
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
[tableview reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];