Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/98.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios UITableview删除行后重新加载数据_Ios_Objective C_Uitableview_Reloaddata - Fatal编程技术网

Ios UITableview删除行后重新加载数据

Ios UITableview删除行后重新加载数据,ios,objective-c,uitableview,reloaddata,Ios,Objective C,Uitableview,Reloaddata,我有一个UITableview,其中包含从后端获取的“课程”数据。用户可以通过单元格上的2个UIButton接受或拒绝课程 问题是,如果用户拒绝多个课程,按钮似乎不会更新并拒绝错误的课程 下面是我如何添加我的uibutton: UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"userWaitingCell" forIndexPath:indexPath]; UIButt

我有一个UITableview,其中包含从后端获取的“课程”数据。用户可以通过单元格上的2个UIButton接受或拒绝课程

问题是,如果用户拒绝多个课程,按钮似乎不会更新并拒绝错误的课程

下面是我如何添加我的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 ;
    }
}
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
按钮时,将调用与它们相关的函数。并且specific
UITableViewCell
中的specific按钮作为参数传递到此函数中。从这个
UIButton
我们找到了祖先
UITableViewCell
,从那里我们得到了按钮用户按下的
nsindepath
。我相信这比像您那样通过增加
+10000
来使用标记更容易出错

您是否检查了标签设置是否正确?NSLog每个按钮标记的设置以及将按钮添加到单元格中的按钮对象的地址。然后还打印激活的地址按钮对象及其标记。另外,请确保您没有多次添加按钮。如果使用dequeReusableCellWithIdentifier,当单元格被重复使用时,屏幕上可能会有按钮吗?您必须在每次分配单元格内容之前清除单元格,以确保其已清除。谢谢您的回答,但我做了一些测试,没有正确地确定错误,错误发生在我拒绝第一个错误后(第一个错误正确消失),然后其他的一个不会消失或做任何事情,无论我点击哪个单元格,tmpURL NSLog总是相同的ID。但是第一个总是有效的。有时是后两个,有时不是。当我在CellForRowatineXpath中打印按钮标签时,在第一次删除之后,它就乱七八糟了。我这样创建我的单元格:UITableViewCell*cell=[tableView dequeueReusableCellWithIdentifier:@“userWaitingCell”forIndexPath:indexPath];我需要清除一些东西吗?你每次都必须完全设置你的单元格。删除单元格时,该单元格将重新用于下一个单元格。所以,如果你在一个单元格中添加按钮,你必须清除任何现有的按钮,以防它是一个重复使用的单元格。是的,但我并没有真正创建一个按钮,因为我在情节提要中设置了我的单元格。我像在第一篇文章中那样,按标签按按钮,那么为什么它没有给出正确的标签号呢?还有,为什么我只想删除它,所以它会重复使用该单元?是否可以在没有重用标识符的情况下使用情节提要单元格?感谢您的帮助,这是一个标记问题!