UITableView reloadData 从单元格中丢失元素

Posted

技术标签:

【中文标题】UITableView reloadData 从单元格中丢失元素【英文标题】:UITableView reloadData lose elements from cell 【发布时间】:2014-10-23 15:01:34 【问题描述】:

我有一个 UITableView,他的数据源是一个在我的界面中声明的 NSMutableArray:

@property (strong, nonatomic) NSMutableArray *arrElements;

现在我以这种方式实现了一个简单的“加载更多”:

    - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView

    float endScrolling = scrollView.contentOffset.y + scrollView.frame.size.height;
    if (endScrolling >= scrollView.contentSize.height)
    
        //only if i have others results i will call load more
        if([self.items_amount integerValue] > self.arrElements.count) 

            if(DEBUG_MODE == 1) 
                NSLog(@"Load more");
            

            //get start param from array size and call load more
            NSNumber *start = [NSNumber numberWithInteger:([self.arrElements count]+1)];
            NSArray *passParams = [NSArray arrayWithObjects:self.menuItem,start,[NSNumber numberWithInteger:NUM_RESULTS_FOR_PAGE], nil];
            [self performSelector:@selector(loadMore:) withObject:passParams afterDelay:0.1];

        
    

这是我的 loadMore 方法:

//load more elements
- (void)loadMore:(NSArray *)arrParams 

    //(MenuItem *)menuItem startingFrom:(NSNumber *)start numResults:(NSNumber *)results;

    MenuItem *menuItem  = [arrParams objectAtIndex:0];
    NSNumber *start     = [arrParams objectAtIndex:1];
    NSNumber *results    = [arrParams objectAtIndex:2];

    if(DEBUG_MODE == 1) 
        NSLog(@"Before load more %lu", (unsigned long)[self.arrElements count]);
    

    //call API and parse it
    WebServicesClient *restClient = [[WebServicesClient alloc] init];
    NSData *data = [restClient callWorkAPI:[menuItem pathAPI] inLanguage:[[NSLocale preferredLanguages] objectAtIndex:0] withLat:self.latitude withLng:self.longitude startingFrom:start numRows:results];
    for(Work* work in [[restClient parseWorks:data] objectForKey:@"items"]) 
        [self.arrElements addObject:work];
    

    if(DEBUG_MODE == 1) 
        NSLog(@"After load more %lu", (unsigned long)[self.arrElements count]);
    

    [self.tableElem reloadData];


这是我的自定义单元格:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 

        static NSString *CellIdentifier;
        CellIdentifier = @"HomeCell";

        HomeCell *cell = (HomeCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

        if(!cell) 
            cell = [[HomeCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        

        Work *work = (Work *)[[self arrElements] objectAtIndex:indexPath.row];

        cell.backgroundColor = [UIColor clearColor];
        cell.labelTitleItem.text = [work title];
        cell.labelSubtitleItem.text = @"my category"


        //if exists image
        if([[work image] isKindOfClass:[NSString class]] && [[work image] length] > 0) 

            dispatch_async(dispatch_get_global_queue(0,0), ^
                NSData * data = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString:[work image]]];
                if ( data == nil )
                    return;
                dispatch_async(dispatch_get_main_queue(), ^
                    cell.imageItem.image = [UIImage imageWithData: data];
                );
            );

         else 
            //remove image setting height to 0
            [cell.imageItem setFrame:CGRectMake(cell.imageItem.frame.origin.x, cell.imageItem.frame.origin.y, cell.imageItem.frame.size.width, 0)];
        


        if([[work distance] isKindOfClass:[NSString class]]) 
            [cell.imagePriority setBackgroundColor:[UIColor lightGrayColor]];
            cell.labelDistanceItem.text = [self convertDistance:[work distance]];
            cell.labelDistanceItem.textColor = [UIColor whiteColor];
         else 
            //remove image setting height to 0
            [cell.imagePriority setFrame:CGRectMake(cell.imagePriority.frame.origin.x, cell.imagePriority.frame.origin.y, cell.imagePriority.frame.size.width, 0)];
            //remove label distance setting height to 0
            [cell.labelSubtitleItem setFrame:CGRectMake(cell.labelSubtitleItem.frame.origin.x, cell.labelSubtitleItem.frame.origin.y, cell.labelSubtitleItem.frame.size.width, 0)];
        

        return cell;

    

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 

    return 1;



- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
    return [[self arrElements] count];

现在的问题是,在 reloadData 之后,我丢失了 CustomCell 的 UILabel(我的类别)的文本 请问有什么建议吗?

【问题讨论】:

嘿,我们可以看看你的 cellforrowatindexpath 和 numberofsections 当然,我编辑了问题 我调试了更多,我发现如果我按下按钮时调用 reloadData 也会出现问题:( 对不起,我刚下班。在 cellforrow 中尝试检查 indexpath.row 是否等于您的 arrElements 计数减 1,然后调用该 loadMore 方法。然后尝试向上拖动你的tableview,应该调用cellforrow方法。 【参考方案1】:

我在使用 TalbeViews 时遇到过类似的问题。尝试使用方法

- (void) tableView:(UITableView *)tableView willDisplayCell:(RCGameTableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath

添加您想要的元素。保持你在 cellForRowAtIndexPath 开始时所做的单元格初始化,然后在我提到的willDisplayCell 委托函数中立即返回单元格并设置背景颜色、标签、图像等。

【讨论】:

以上是关于UITableView reloadData 从单元格中丢失元素的主要内容,如果未能解决你的问题,请参考以下文章

UITableView.reloadData() 没有刷新 tableView。没有错误信息

UITableView 的 reloadData() 的替代方案?

UIView 与 UITableview 和 UIImageview,使用 reloadData 访问 UITableview

UITableView 强制 sectionIndex 更新而不调用 reloadData

iOS UITableView reloadData 刷新结束后执行后续操作

调用 reloadData 时 UITableView 有不需要的动画