如何在 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 添加视图?的主要内容,如果未能解决你的问题,请参考以下文章