删除行后 UITableview 重新加载数据
UITableview reloading data after deleting row
我有一个 UITableview,其中 "lessons" 从后端获取数据。用户可以使用单元格上的 2 个 ui 按钮接受或拒绝课程。
问题是如果用户拒绝多节课,按钮好像没有更新,拒绝错误的课。
这是我添加 uibutton 的方法:
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 ;
}
}
您似乎是通过在情节提要中设置的标签获取按钮:200 和 201。
在您的代码中,您将按钮的标签更改为新值:
`[[dic objectForKey:@"id"] integerValue] + 10000`
此时您已经更改了单元格中这些按钮的标签。
在下一次 [self myTableView reloadData];
调用中,将重复使用而不是创建单元格。 None 这些单元格将具有有效标记为 200 或 201 的视图。
按钮将具有您第一次添加的原始操作。
最快的解决方案:
1) CTLR 将您的按钮拖入 IB 单元格 header 并为每个按钮创建一个 IBOutlet:acceptButton
和 cancelButton
说。这使您的代码能够直接在代码中引用按钮。不要使用标记 200 和 201,因为它们不再需要。
2) 在您的单元格创建代码中,删除标签 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 - 将您的按钮原型拖到您的 table 视图 header 中并为每个按钮添加一个 IBAction。因此,请使用您现在拥有的相同代码来执行操作。
这将阻止发生标签冲突,我很确定这是您的问题。
而不是设置 tag
s 我会推荐一个更稳定的选项:
此方法找到一个 UIView
与您声明的 class 并且它是您提供的视图的父视图:
- (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];
}
基本上发生的事情是,当按下 refuseLesson
和 acceptLesson
按钮时,将调用绑定它们的函数。并将特定 UITableViewCell
中的特定按钮作为参数传递给此函数。从这个 UIButton
我们找到祖先 UITableViewCell
并从那里我们得到用户按下的按钮的 NSIndexPath
。我相信这比通过递增 +10000
来使用标签更不会出错
我有一个 UITableview,其中 "lessons" 从后端获取数据。用户可以使用单元格上的 2 个 ui 按钮接受或拒绝课程。
问题是如果用户拒绝多节课,按钮好像没有更新,拒绝错误的课。
这是我添加 uibutton 的方法:
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 ;
}
}
您似乎是通过在情节提要中设置的标签获取按钮:200 和 201。
在您的代码中,您将按钮的标签更改为新值:
`[[dic objectForKey:@"id"] integerValue] + 10000`
此时您已经更改了单元格中这些按钮的标签。
在下一次 [self myTableView reloadData];
调用中,将重复使用而不是创建单元格。 None 这些单元格将具有有效标记为 200 或 201 的视图。
按钮将具有您第一次添加的原始操作。
最快的解决方案:
1) CTLR 将您的按钮拖入 IB 单元格 header 并为每个按钮创建一个 IBOutlet:acceptButton
和 cancelButton
说。这使您的代码能够直接在代码中引用按钮。不要使用标记 200 和 201,因为它们不再需要。
2) 在您的单元格创建代码中,删除标签 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 - 将您的按钮原型拖到您的 table 视图 header 中并为每个按钮添加一个 IBAction。因此,请使用您现在拥有的相同代码来执行操作。
这将阻止发生标签冲突,我很确定这是您的问题。
而不是设置 tag
s 我会推荐一个更稳定的选项:
此方法找到一个 UIView
与您声明的 class 并且它是您提供的视图的父视图:
- (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];
}
基本上发生的事情是,当按下 refuseLesson
和 acceptLesson
按钮时,将调用绑定它们的函数。并将特定 UITableViewCell
中的特定按钮作为参数传递给此函数。从这个 UIButton
我们找到祖先 UITableViewCell
并从那里我们得到用户按下的按钮的 NSIndexPath
。我相信这比通过递增 +10000
来使用标签更不会出错