如何在 iOS 中异步向 UITableViewCell 添加视图?

Posted

技术标签:

【中文标题】如何在 iOS 中异步向 UITableViewCell 添加视图?【英文标题】:How to add views to a UITableViewCell asynchronously in iOS? 【发布时间】:2016-10-10 11:41:27 【问题描述】:

在我的应用程序中,我有一个带有巨大 UITableViewCell 的 UITableView。每个单元格都是动态的,并在运行时创建。通过说动态不仅内容,而且布局也是动态的。问题是,它花费的时间太长,滚动时会卡顿。特别是当一个新的单元格进入屏幕时,至少有 1 秒的冻结。

有什么方法可以提高这种性能吗?我查看了有关异步加载单元格的教程:

https://blog.uship.com/shippingcode/populating-uitableviewcells-asynchronously-to-fix-uitableview-lag/

但是,本教程展示了如何将数据异步加载到静态单元格中。我需要将动态数据加载到动态布局中。

【问题讨论】:

您需要哪种语言的解决方案? objc c 还是 swift ? 我正在使用 swift。但此时任何解决方案都可以。我没有选择。 你有来自服务器的单元格上的图像吗?还是只是数据? 我有很多不同的东西,具体取决于对象。它可以有图像标签文本字段、电子表格、滚动视图、条形图等......基本上一切。 【参考方案1】:

这里有一些建议,希望对你有所帮助

1>> 尝试通过在单元格 xib 中提供可重用标识符来重用您的 tableview 单元格(如果单元格是自定义的)。

2>> 检查 cellForTheRowAtIndexPath 方法中的循环(不要在其中执行循环)。

3>> 如果您在 cellForTheRowAtIndexPath 方法中下载一些数据,例如图像,请确保您异步下载。

4>> 执行 UI 任务,比如在主线程的单元格中设置图像

[NSOperationQueue mainQueue]addOperationWithBlock:
];

5>> 像许多 if 和 else 语句一样,cellForTheRowAtIndexPath 方法中的 Ovoid 过度调节。

【讨论】:

我不能真正重复使用这些单元格,因为它们每个都是不同的。 在 cellForRowAtIndexPathMethod 的主线程上设置标签中的图像或数据。 [NSOperationQueue mainQueue]addOperationWithBlock: ]; 感谢您的提示。我在 cellForRow 方法中有很多条件。会减少他们一点。【参考方案2】:

在 cellForRowAtIndexPath 方法中试试。我在单元格上添加了一个自定义视图,并在该自定义视图上添加了一个图像视图。你可以添加 UILabel、UIButton 或任何东西。

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

    NSString * CellIndentifier = @"CellIndentifier";

    UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:nil];

    if(cell == nil)
    
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIndentifier];

        cell.backgroundColor = [UIColor clearColor];
        cell.selectionStyle = UITableViewCellSelectionStyleDefault;
    


 UIView *cellVW ;
 UIImageView *logoImg;

cellVW = [[UIView alloc] initWithFrame:CGRectMake(10, 2, tableView.frame.size.width-20, 216)];
cellVW.backgroundColor = [UIColor clearColor];
cellVW.layer.cornerRadius = 5;
cellVW.layer.borderWidth = 1;
cellVW.layer.borderColor = [[UIColor lightGrayColor] CGColor];
[cell addSubview:cellVW];

logoImg = [[UIImageView alloc] init];
logoImg.frame = CGRectMake(10, 5, tableView.frame.size.width-20, 140);
logoImg.backgroundColor = [UIColor clearColor];
logoImg.layer.borderColor = [[UIColor lightGrayColor] CGColor];




 NSURL *imageURL = [NSURL URLWithString:@"https://upload.wikimedia.org/wikipedia/en/a/a9/Example.jpg"];
[NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:imageURL] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
 

     if(error == nil)
     
         NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;

         if([httpResponse statusCode] == 200)
         
             UIImage *image = [UIImage imageWithData:data];

             logoImg.image = image;


         
         else
         

         
     
 ];



    [cellVW addSubview:logoImg];

    return cell;


 

【讨论】:

这假设单元格中有一个 UIImageView 开始。我还需要异步创建 UIImageView。 这里显示了两个步骤。在线程中创建元素,并在本地或从服务器设置它们的值。这是迄今为止的规则。您的主要目标应该是避免冻结 UI。你的目标是什么? 参见您的参考代码:我看过他们的动画。我做过很多次这样的工作。注意这一行: dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), () -> Void in let text = self.model.textForIndexPath(indexPath) dispatch_async(dispatch_get_main_queue(), () -> Void in cell.textLabel? .text = 文本 ) ) 我又修改了一步。对于创建 uiview、uilabel、uibutton,UI 不会妨碍。 UI 实际上阻碍了数据。 我会尝试实现这样的东西,看看会发生什么。谢谢。

以上是关于如何在 iOS 中异步向 UITableViewCell 添加视图?的主要内容,如果未能解决你的问题,请参考以下文章

Node JS、Socket.io、异步和阻塞事件循环

iOS:在while循环中带有块回调的异步方法

java客户端如何向服务器txt文件写入信息

如何在 React 应用程序中使用 JEST 测试向 api 发出 axios 请求的异步函数

iOS UI控件7(UITableView)

向 Axios 请求。如何解决异步问题?