删除行后 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:acceptButtoncancelButton 说。这使您的代码能够直接在代码中引用按钮。不要使用标记 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。因此,请使用您现在拥有的相同代码来执行操作。

这将阻止发生标签冲突,我很确定这是您的问题。

而不是设置 tags 我会推荐一个更稳定的选项:

此方法找到一个 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];
}

基本上发生的事情是,当按下 refuseLessonacceptLesson 按钮时,将调用绑定它们的函数。并将特定 UITableViewCell 中的特定按钮作为参数传递给此函数。从这个 UIButton 我们找到祖先 UITableViewCell 并从那里我们得到用户按下的按钮的 NSIndexPath 。我相信这比通过递增 +10000 来使用标签更不会出错