Ios UITableview删除行后重新加载数据
我有一个UITableview,其中包含从后端获取的“课程”数据。用户可以通过单元格上的2个UIButton接受或拒绝课程 问题是,如果用户拒绝多个课程,按钮似乎不会更新并拒绝错误的课程 下面是我如何添加我的uibutton:Ios UITableview删除行后重新加载数据,ios,objective-c,uitableview,reloaddata,Ios,Objective C,Uitableview,Reloaddata,我有一个UITableview,其中包含从后端获取的“课程”数据。用户可以通过单元格上的2个UIButton接受或拒绝课程 问题是,如果用户拒绝多个课程,按钮似乎不会更新并拒绝错误的课程 下面是我如何添加我的uibutton: UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"userWaitingCell" forIndexPath:indexPath]; UIButt
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"userWaitingCell" forIndexPath:indexPath];
UIButton *acceptBtn = (UIButton *)[cell viewWithTag:200];
acceptBtn.tag = [[dic objectForKey:@"id"] integerValue] + 10000;
[acceptBtn addTarget:self action:@selector(acceptLesson:) forControlEvents:UIControlEventTouchUpInside];
UIButton *refuseBtn = (UIButton *)[cell viewWithTag:201];
refuseBtn.tag = [[dic objectForKey:@"id"] integerValue] + 10000;
[refuseBtn addTarget:self action:@selector(refuseLesson:) forControlEvents:UIControlEventTouchUpInside];
NSLog(@"Btn TAG: %ld", (long)refuseBtn.tag);
return cell;
我使用后端数据库中课程的唯一ID设置标记
下面是我如何处理用户点击按钮:
- (void)refuseLesson:(id)sender
{
UIButton *senderBtn = (UIButton *)sender;
NSString *tmpUrl = [NSString stringWithFormat:@"%@%ld",
@"lesson/refuse/", senderBtn.tag - 10000];
NSLog(@"tmpUrL : %@", tmpUrl);
[dbService sendPostRequest:tmpUrl];
}
在这里,我可以在NSLog中看到它是错误的课程ID
当我完成请求时,我将如下设置我的数据数组:
for (int i = 0; i < [lessonList count]; i++)
{
NSMutableDictionary *lesson = [lessonList objectAtIndex:i];
if ([[lesson objectForKey:@"id"] integerValue] == [[dataDic objectForKey:@"id"] integerValue])
{
if ([[dataDic objectForKey:@"invitationStatus"] isEqualToString:@"accepted"])
{
[lesson setObject:@"accepted" forKey:@"invitationStatus"];
[lesson setObject:[dataDic objectForKey:@"lesson_count"] forKey:@"lesson_count"];
[lesson setObject:[dataDic objectForKey:@"lesson_done"] forKey:@"lesson_done"];
}
else if ([[dataDic objectForKey:@"invitationStatus"] isEqualToString:@"refused"])
{
[lesson setObject:@"refused" forKey:@"invitationStatus"];
[lessonList removeObjectAtIndex:i];
}
[self.myTableView reloadData];
NSLog(@"RELOADING");
return ;
}
}
for(int i=0;i<[lessonList count];i++)
{
NSMutableDictionary*lesson=[lessonList objectAtIndex:i];
如果([[lesson objectForKey:@“id”]integerValue]==[[dataDic objectForKey:@“id”]integerValue])
{
如果([[dataDic objectForKey:@“invitationStatus”]IseQualtString:@“accepted”])
{
[lesson setObject:@“已接受”forKey:@“邀请状态”];
[lesson setObject:[dataDic objectForKey:@“lesson_count”]forKey:@“lesson_count”];
[lesson setObject:[dataDic objectForKey:@“lesson_done”]forKey:@“lesson_done”];
}
如果([[dataDic objectForKey:@“invitationStatus”]IsequalString:@“拒绝”])
{
[lesson setObject:@“拒绝”forKey:@“邀请状态”];
[lessonList removeObjectAtIndex:i];
}
[self.myTableView重新加载数据];
NSLog(“重新加载”);
返回;
}
}
您似乎是通过在故事板中设置的标签来获取按钮:200和201
在代码中,然后将按钮的标记更改为新值:
`[[dic objectForKey:@"id"] integerValue] + 10000`
此时,您已经更改了单元格中这些按钮的标记
在下一个[self myTableView reloadData]代码>调用,单元格将被重用而不是创建。这些单元格都不会具有有效标记为200或201的视图
按钮将具有您第一次添加的原始动作
最快的解决方案:
1) CTLR将IB按钮拖动到单元格标题中,并为每个按钮创建一个IBOutlet:acceptButton
和cancelButton
say。这使您的代码能够直接在代码中引用按钮。不要使用标签200和201,因为它们不再需要
2) 在单元格创建代码中,删除fetchby标记200和201并直接引用它们。比如:
UIButton *acceptBtn = cell.acceptButton;
acceptBtn.tag = [[dic objectForKey:@"id"] integerValue] + 10000;
UIButton *refuseBtn = cell.refuseButton;
refuseBtn.tag = [[dic objectForKey:@"id"] integerValue] + 10000;
NSLog(@"Btn TAG: %ld", (long)refuseBtn.tag);
return cell;
3) CTRL-将按钮原型拖动到表视图标题中,并为每个按钮添加iAction。因此,使用与现在相同的代码进行操作
这将阻止标签冲突的发生,我很确定这是您的问题。我建议使用更稳定的选项,而不是设置tag
s:
此方法查找带有您声明的类的ui视图
,该类是您提供的视图的超级视图:
- (id) findAncestorOfView: (UIView *) view WithClass: (Class) clss
{
while (view && ![view isKindOfClass:clss])
view = [view superview];
return view;
}
并按如下方式调用该方法:
- (void)refuseLesson:(id)sender
{
UITableViewCell *cell = (UITableViewCell *)[self findAncestorOfView:sender WithClass:[UITableViewCell class]];
NSIndexPath * indexPath = [self.tableView indexPathForCell:cell];
NSDictionary * dic = [lessonList objectAtIndex:indexPath.row];
NSString *tmpUrl = [NSString stringWithFormat:@"%@%@",
@"lesson/refuse/", [dic objectForKey:@"id"];
NSLog(@"tmpUrL : %@", tmpUrl);
[dbService sendPostRequest:tmpUrl];
}
基本情况是,当按下refuelesson
和acceptLesson
按钮时,将调用与它们相关的函数。并且specificUITableViewCell
中的specific按钮作为参数传递到此函数中。从这个UIButton
我们找到了祖先UITableViewCell
,从那里我们得到了按钮用户按下的nsindepath
。我相信这比像您那样通过增加+10000
来使用标记更容易出错您是否检查了标签设置是否正确?NSLog每个按钮标记的设置以及将按钮添加到单元格中的按钮对象的地址。然后还打印激活的地址按钮对象及其标记。另外,请确保您没有多次添加按钮。如果使用dequeReusableCellWithIdentifier,当单元格被重复使用时,屏幕上可能会有按钮吗?您必须在每次分配单元格内容之前清除单元格,以确保其已清除。谢谢您的回答,但我做了一些测试,没有正确地确定错误,错误发生在我拒绝第一个错误后(第一个错误正确消失),然后其他的一个不会消失或做任何事情,无论我点击哪个单元格,tmpURL NSLog总是相同的ID。但是第一个总是有效的。有时是后两个,有时不是。当我在CellForRowatineXpath中打印按钮标签时,在第一次删除之后,它就乱七八糟了。我这样创建我的单元格:UITableViewCell*cell=[tableView dequeueReusableCellWithIdentifier:@“userWaitingCell”forIndexPath:indexPath];我需要清除一些东西吗?你每次都必须完全设置你的单元格。删除单元格时,该单元格将重新用于下一个单元格。所以,如果你在一个单元格中添加按钮,你必须清除任何现有的按钮,以防它是一个重复使用的单元格。是的,但我并没有真正创建一个按钮,因为我在情节提要中设置了我的单元格。我像在第一篇文章中那样,按标签按按钮,那么为什么它没有给出正确的标签号呢?还有,为什么我只想删除它,所以它会重复使用该单元?是否可以在没有重用标识符的情况下使用情节提要单元格?感谢您的帮助,这是一个标记问题!