UICollectionView 滚动冻结与 NSData (imageView)
UICollectionView Scroll Freeze with NSData (imageView)
我在同一页面中使用了 UICollectionView 和 UITableView。我将 SDWebImage
与 UITableView
一起使用,并且工作正常。我正在尝试将 SDWebImage
与 UICollectionView
一起使用,但无法成功。所以我使用了 NSData 但它冻结了。我该如何解决这个问题?
更新:有没有办法将 SDWebImage
与 UICollectionView
一起使用?
我的代码:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *simpleTableIdentifier = @"cell";
ProductsCollectionViewCell *pCell = [_collection dequeueReusableCellWithReuseIdentifier:simpleTableIdentifier forIndexPath:indexPath];
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[_arrayImage objectAtIndex:indexPath.row]]];
_imgCollection = (UIImageView *)[pCell viewWithTag:100];
_imgCollection.image = [UIImage imageWithData:imageData];
pCell.layer.shouldRasterize = YES;
pCell.layer.rasterizationScale = [UIScreen mainScreen].scale;
}
我的 table 查看代码
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = @"productCell";
ProductsTableViewCell *pCell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
[pCell.imgProduct sd_setImageWithURL:[NSURL URLWithString:[_arrayImage objectAtIndex:indexPath.row]]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
可能是您缺少 contentView
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *simpleTableIdentifier = @"cell";
ProductsCollectionViewCell *pCell = [_collection dequeueReusableCellWithReuseIdentifier:simpleTableIdentifier forIndexPath:indexPath];
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[_arrayImage objectAtIndex:indexPath.row]]];
_imgCollection = (UIImageView *)[pCell.contentView viewWithTag:100];
_imgCollection.image = [UIImage imageWithData:imageData];
}
您使用的方法
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[_arrayImage objectAtIndex:indexPath.row]]];
是同步的,这意味着它会阻塞线程直到它完成。 (这就是它冻结的原因)
我建议你想办法在你的代码中使用 SDWebImage
,如果你告诉我们为什么它不起作用,我们可能会帮助你。
编辑:
查看 SDWebImage
的 documentation 中的第一个示例,特别是这一行:
[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
现在用它代替你的这行代码:
_imgCollection.image = [UIImage imageWithData:imageData];
另外,去掉你下载图片的行。
莫非
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL ...
是否在主线程上执行耗时操作?
为什么不像这样把抓取放在后台呢?
dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL* url = [NSURL URLWithString:[_arrayImage objectAtIndex:indexPath.row]]
NSData *imageData = [NSData dataWithContentsOfURL:url];
dispatch_async(dispatch_get_main_queue(), ^{
UICollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath];
if(cell) { // cell is visible
cell.imageView.image = [UIImage imageWithData:imageData];
}
});
});
最后,确保
[_arrayImage objectAtIndex:indexPath.row]
确实是一个字符串,_arrayImage是一个字符串数组
最后我会考虑把
[UIImage imageWithData:imageData]
在后台以及解码也可能很耗时
我在同一页面中使用了 UICollectionView 和 UITableView。我将 SDWebImage
与 UITableView
一起使用,并且工作正常。我正在尝试将 SDWebImage
与 UICollectionView
一起使用,但无法成功。所以我使用了 NSData 但它冻结了。我该如何解决这个问题?
更新:有没有办法将 SDWebImage
与 UICollectionView
一起使用?
我的代码:
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *simpleTableIdentifier = @"cell";
ProductsCollectionViewCell *pCell = [_collection dequeueReusableCellWithReuseIdentifier:simpleTableIdentifier forIndexPath:indexPath];
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[_arrayImage objectAtIndex:indexPath.row]]];
_imgCollection = (UIImageView *)[pCell viewWithTag:100];
_imgCollection.image = [UIImage imageWithData:imageData];
pCell.layer.shouldRasterize = YES;
pCell.layer.rasterizationScale = [UIScreen mainScreen].scale;
}
我的 table 查看代码
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = @"productCell";
ProductsTableViewCell *pCell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
[pCell.imgProduct sd_setImageWithURL:[NSURL URLWithString:[_arrayImage objectAtIndex:indexPath.row]]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
可能是您缺少 contentView
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
static NSString *simpleTableIdentifier = @"cell";
ProductsCollectionViewCell *pCell = [_collection dequeueReusableCellWithReuseIdentifier:simpleTableIdentifier forIndexPath:indexPath];
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[_arrayImage objectAtIndex:indexPath.row]]];
_imgCollection = (UIImageView *)[pCell.contentView viewWithTag:100];
_imgCollection.image = [UIImage imageWithData:imageData];
}
您使用的方法
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[_arrayImage objectAtIndex:indexPath.row]]];
是同步的,这意味着它会阻塞线程直到它完成。 (这就是它冻结的原因)
我建议你想办法在你的代码中使用 SDWebImage
,如果你告诉我们为什么它不起作用,我们可能会帮助你。
编辑:
查看 SDWebImage
的 documentation 中的第一个示例,特别是这一行:
[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
现在用它代替你的这行代码:
_imgCollection.image = [UIImage imageWithData:imageData];
另外,去掉你下载图片的行。
莫非
NSData *imageData = [NSData dataWithContentsOfURL:[NSURL ...
是否在主线程上执行耗时操作?
为什么不像这样把抓取放在后台呢?
dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL* url = [NSURL URLWithString:[_arrayImage objectAtIndex:indexPath.row]]
NSData *imageData = [NSData dataWithContentsOfURL:url];
dispatch_async(dispatch_get_main_queue(), ^{
UICollectionViewCell* cell = [collectionView cellForItemAtIndexPath:indexPath];
if(cell) { // cell is visible
cell.imageView.image = [UIImage imageWithData:imageData];
}
});
});
最后,确保
[_arrayImage objectAtIndex:indexPath.row]
确实是一个字符串,_arrayImage是一个字符串数组
最后我会考虑把
[UIImage imageWithData:imageData]
在后台以及解码也可能很耗时