UITableView重新创建滚动单元格

时间:2015-10-08 11:04:38

标签: ios objective-c uitableview

我无法解决这个问题。我正在开发一个具有时间轴的应用程序,在单元格中有一个图像,一些按钮和标签。每个单元格中有三个按钮,一个是爱,第二个是评论,第三个是共享,如图所示。enter image description here
当用户选择爱情按钮时,我已经编码它改变了它的图像是filled-heart-icon,就像在Instagram上一样。更改图像意味着呼叫已发送到网络服务器,现在如果页面刷新,它将保持图像的原样。这样做只是为了让用户感觉他的更改已经完成,因此应用程序会在后面发送此更改数据,并且用户没有因为它而感到任何滞后。
但是如果用户喜欢图片并向下滚动以使图像不在屏幕上,然后决定向上滚动,该图像将再次出现heart-icon而不是filled-heart-icon,但如果他刷新时间线,它将会是更改为filled-heart-icon。所以当一个单元格返回到屏幕的活动部分时,它会更改为上次下载内容的状态。我已经检查了我的代码,并且没有再次刷新它或其他任何内容的电话。我的问题是我在哪里可以找到这个问题。我已经检查了我的cellForRowAtIndexPath方法三次,但一无所获。如果有需要,我会在这里添加代码,但我认为它更多的是需要解决的表的属性。
我在HomeCell.m班级中立即更改了心脏图标:

if ([self.loveBtn.currentImage isEqual:[UIImage imageNamed:@"heart-icon-filled"]])
    {
        [self.loveBtn setImage:[UIImage imageNamed:@"heart-icon"] forState:UIControlStateNormal];
    }
    else
    {
        [self.loveBtn setImage:[UIImage imageNamed:@"heart-icon-filled"] forState:UIControlStateNormal];
    }

如果时间线刷新,则根据服务器响应改变图标,即1表示喜欢0意味着不喜欢。下面这张图片几乎是我写的所有内容,可以让您清楚地了解问题。 enter image description here

这是如何为爱情按钮生成呼叫。在我的HomeViewController首先有时间轴的情况下,我已在NSNotifications注册了ViewWillApear

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(HomeLovePostSuccess) name:@"HomeLovePostSuccess" object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(HomeLovePostFail:) name:@"HomeLovePostFail" object:nil];

并且在HomeLovePostSuccess方法中,这就是我实际上没有做任何事情: - (无效)HomeLovePostSuccess {     NSString * uid = [[NSUserDefaults standardUserDefaults] objectForKey:USERID];     NSDictionary * dict = [[NSDictionary alloc] initWithObjectsAndKeys:uid,@" uid",nil]; }  但在我的cellForRowAtIndexPath我正在呼叫网络服务器:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
HomeCell *cellObj = (HomeCell*)[tableView dequeueReusableCellWithIdentifier:@"HomeCell" ];
if ([[isLikeArr objectAtIndex:indexPath.row] isEqualToString:@"1"]) {
                    [cellObj.loveBtn setImage:[UIImage imageNamed:@"heart-icon-filled"] forState:UIControlStateNormal];

                }
                else
                {
                    [cellObj.loveBtn setImage:[UIImage imageNamed:@"heart-icon"] forState:UIControlStateNormal];
                }
return cellObj;
}

我认为这与dequeueReusableCellWithIdentifier有关。

2 个答案:

答案 0 :(得分:0)

这与你如何加载和保存按钮的状态有关。在大多数情况下,您将使用Model对象中的信息来保存有关单元格的不同属性。您可以在调用tableView cellForRowAtIndexPath时使用此对象,在您的情况下,您将使用Bool表示喜欢或不喜欢的内容。当您将状态发送到服务器,并将“喜欢”状态设置为true时,您还需要更新模型中的Bool状态。这样,当您的单元格在屏幕外,然后再次加载到cellForRowAtIndexPath时,它就会知道将其状态更改为“喜欢”。

由于你没有包含任何代码,很难说出你在做什么,所以显示代码会更有帮助,因为我假设你的解决方案是用来保存喜欢的状态

答案 1 :(得分:0)

您需要专注于您的MVC设计。在这种情况下,您的HomeCell查看HomeViewController控制器,并将模型的每个单元格传递给tableView:cellForRowAtIndexPath:

您大部分时间都在这样做,但模型不完整。喜欢没有考虑的项目有一个临时阶段。

考虑这样的事情:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   HomeCell *cellObj = (HomeCell*)[tableView dequeueReusableCellWithIdentifier:@"HomeCell" ];
   if ([[isLikeArr objectAtIndex:indexPath.row] isEqualToString:@"1"] ||
       [self.objectsBeingLiked contains:@(indexPath.row)])
   {
      [cellObj.loveBtn setImage:[UIImage imageNamed:@"heart-icon-filled"] forState:UIControlStateNormal];
   }
   else
   {
      [cellObj.loveBtn setImage:[UIImage imageNamed:@"heart-icon"] forState:UIControlStateNormal];
   }
   return cellObj;
}

objectsBeingLiked将是NSMutableSet,其中包含用户请求喜欢的任何项目的索引,但服务器响应仍处于待处理状态。如果有更适合放置在集合中的内容,请使用它。我把它留给你判断。

此外,您的HomeLovePostSuccessHomeLovePostFail:方法可用于重新加载相应的单元格以指示加载已完成。如果您使用我的上述建议,则需要在调用这些方法时从objectsBeingLiked中删除必要的索引。