UITableViewCell 不显示加载的数据,但在选择时显示它

Posted

技术标签:

【中文标题】UITableViewCell 不显示加载的数据,但在选择时显示它【英文标题】:UITableViewCell Doesn't display loaded data but displays it when selected 【发布时间】:2014-02-20 11:45:11 【问题描述】:

我面临一个奇怪的问题,我确信我做错了什么。在我的 UITableViewController 类中,我有一个函数如下:

-(void)EERefreshView

    NSLog(@"App delegate requested the view be refreshed");
    [self loadEventsFromDB];

    for(int a=0;a<eventsList.count;a++)
    

        DB_EEEvent *event = (DB_EEEvent*)eventsList[a];
        UITableViewCell *cell =
        [self.tableView dequeueReusableCellWithIdentifier:@"Cell"];
        //NSLog(@"CellID %@", cell.reuseIdentifier);


        //get references to the UI components
        UILabel *lblTitle = (UILabel*)[cell.contentView viewWithTag:5];
        UILabel *lblDate = (UILabel*) [cell.contentView viewWithTag:6];
        UIImageView *imgEvent = (UIImageView*)[cell.contentView viewWithTag:7];

        //set values
        lblTitle.text = event.name;

        lblDate.text = [NSString stringWithFormat:@"%@ - %@",
                        event.startdate,event.enddate];

        AppDelegate *del = [AppDelegate sharedAppDelegate]; //need this to get the BaseURL

        // Here we use the new provided setImageWithURL: method to load the web image
        NSString * imageURL =[[NSString alloc] initWithFormat:@"http://%@%@",del.api.BaseURL,event.logo];
        NSString* webStringURL = [imageURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        NSURL *url = [NSURL URLWithString:webStringURL];

        [imgEvent setImageWithURL:url placeholderImage:[UIImage imageNamed:@"placeholder.png"] completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) 
            //do somethign when image call completes
        ];

        [eventsListCells addObject:cell];

        if(a == selectedEvent)
        


        
    

    dispatch_async(dispatch_get_main_queue(), ^
        [tblEventsList reloadData];
    );


这个函数加载一个带有 UITableViewCell 对象的数组,然后由

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

    // Configure the cell data
    NSLog(@"IndexPathRow: %d", indexPath.row);
    UITableViewCell *cell =  (UITableViewCell*)eventsListCells[indexPath.row];
    return cell;



但是,当加载单元格时,lblTitle 和 lblDate 中没有显示文本。但是当我点击一个单元格时,它会在标签中显示文本。所以这意味着数据在那里,但在最初创建时它没有被刷新。我怀疑这可能与线程有关,但我不是该主题的专家,希望能得到任何帮助。

【问题讨论】:

为什么在异步调度中调用[tblEventsList reloadData]; @HRM 因为 TableView UI 在主线程中更新。如果我不使用它,那么表格视图将不会自动更新并保持空白,直到我滚动它。顺便说一句,我确实尝试在没有异步块的情况下调用 [tblEventList reloadData],即使在滚动文本之后也不会加载,除非我单击单元格。好像和点击有关系 尝试使用具有不同标识符的dequeueReusableCellWithIdentifier。例如[self.tableView dequeueReusableCellWithIdentifier:[NSString stringWithFormat:@"Cell_%i", a]]; 完全拉出[tblEventsList reloadData];。让视图自己刷新一次,看看会发生什么。我想知道您是否正在更改 async 调用中的单元格,而 UITableView 也正在尝试显示它们。您应该创建单元格,将它们放到桌子上,然后停止触摸它们。这个EERefreshView 方法会被反复调用吗? 【参考方案1】:

我知道是什么困扰着您,以及您创建此方法的原因,但您不需要它。您需要反向线程的唯一原因是您的图像加载,因此应该在 bkg 中抛出。线程和其余代码应该在 -

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

你真的不需要预先创建单元格,而且你不能导致它们是可重复使用的。例如,如果您在 eventsList 中有 50 个元素并且屏幕上只有 5 个单元格的空间,则您无法创建 50 个单元格,因为代码将仅创建 5+1 并在它们出现在屏幕上时重用它们,因此 eventsList 的每个元素都将使用这 5 个单元格中的一个,在另一侧,每个单元格都将成为 eventsList 数组中 10 个不同元素的宿主。所以你可以看到你的代码没有多大意义......

【讨论】:

@AntonioDev 谢谢这确实有道理,但是为什么当我点击它时它会显示数据? 我真的不知道,但是你的问题是微不足道的,并且在大多数 UITableViews 中“已经完成”,所以我真的没有看到调试代码的意义,阅读文档,谷歌它,我相信你会找到很多功能示例......试试 IconDownloader 类(你在 GitHub 上有它),研究这个例子,就是这样。您将多次重复使用此代码... 同意。感谢您对此事的深入了解。【参考方案2】:

您在问题中提到的第二个函数是调用以用数据填充表的函数。当您调用[tblEventsList reloadData]; 时,您的应用程序只需调用(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 方法。所以这个方法需要将数据输出回表。下面是一个非常简单的例子。另外,请确保您的表委托和数据源已设置。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView 
      dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) 
        cell = [[UITableViewCell alloc]
           initWithStyle:UITableViewCellStyleDefault
           reuseIdentifier:CellIdentifier];
    

    // Configure the cell.
    cell.textLabel.text = [self.your_data_source objectAtIndex:[indexPath row]];
    return cell;

【讨论】:

谢谢@Kyle。我知道 reloadData 实际上是在调用 cellForRowAtIndex。我面临的问题是我已经创建了一个我想要使用的单元格数组。当我在 cellForRoWAtIndex 函数中从该数组中返回一个单元格时,它不会从中加载文本。 -1:他对这个方法的实现将单元格返回到表格中,它们刚刚在其他地方创建。 这看起来很奇怪,作为一个快速调试技巧,在 cellForRowAtIndexPath 方法中打印出你的数组。确保它已分配且不为空。可能存在一些奇怪的问题,即数组在加载时为空,但在用户不执行某些操作时被设置。

以上是关于UITableViewCell 不显示加载的数据,但在选择时显示它的主要内容,如果未能解决你的问题,请参考以下文章

Swift 4:UITableViewCell 在初始加载时不会显示数据,但会在第二次加载时加载

UITableViewCell textlabel 内容不显示任何内容

如何在 UITableViewCell 上显示数组数据?

重新加载uitableviewcell,iOs / Swift时随机滚动

无法在 UITableViewCell 内的 UILabel 中显示来自核心数据的 Double

具有动态数据初始化的 UiTableviewCell 未正确加载