[英]UITableView scrolling is not smooth
我在UITableView上使用包含UIImageView的UITableViewCell进行平滑滚动问题。 在StrackOverflow上可以找到类似的问题,但是所提出的解决方案都没有帮助我彻底摆脱滞后。
我的情况很常见:
我遵循了多个优化技巧,并设法优化滚动。 不幸的是它仍然不完美。 这是我的情景:
最初在开始新的后台线程之前获取图像(步骤1)是没有后台线程的UIImage缓存检查。 在这种情况下,如果我们在缓存中有图像,我们会立即分配它,这会在快速滚动期间引入很大的延迟(只要我们立即获取图像,我们就会经常分配图像)。 我在下面的例子中评论了这些行。
还有两个问题:
任何建议如何处理这两个问题或如何优化我的方案表示赞赏
请考虑使用Xamarin编写的示例,但我不相信Xamarin是导致问题的原因,只要我对ObjectiveC中编写的应用程序也有同样的问题。
您是否每个人都尝试使用一个保存在Bundle
120x120图像来填充您的TableView
? 这样,您可以检查Image rendering
是否出现问题
我建议您创建并使用所有图像的缩略图,而不是将所有图像的大小调整为120x120并将其保存在缓存中。 你已经在某种程度上这样做了,但是你这样做了几次(每次你滚动或者你的缓存已经满了)。
在我们的上一个项目中,我们有一个带书籍封面的UICollectionView
。 大多数封面都在400-800kb之间,滚动时的感觉非常糟糕。 所以我们为每个图像创建了一个缩略图(缩略图大约40-50kb),并使用缩略图而不是真正的封面。 奇迹般有效! 我附上了缩略图创建功能
- (BOOL) createThumbnailForImageAtFilePath:(NSString *)sourcePath withName:(NSString *)name {
UIImage* sourceImage = [UIImage imageWithContentsOfFile:sourcePath];
if (!sourceImage) {
//...
return NO;
}
CGSize thumbnailSize = CGSizeMake(128,198);
float imgAspectRatio = sourceImage.size.height / sourceImage.size.width;
float thumbnailAspectRatio = thumbnailSize.height/thumbnailSize.width;
CGSize scaledSize = thumbnailSize;
if(imgAspectRatio >= thumbnailAspectRatio){
//image is higher than thumbnail
scaledSize.width = scaledSize.height * thumbnailSize.width / thumbnailSize.height;
}
else{
//image is broader than thumbnail
scaledSize.height = scaledSize.width * imgAspectRatio;
}
UIGraphicsBeginImageContextWithOptions( scaledSize, NO, 0.0 );
CGRect scaledImageRect = CGRectMake( 0.0, 0.0, scaledSize.width, scaledSize.height );
[sourceImage drawInRect:scaledImageRect];
UIImage* destImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
NSString* thumbnailFilePath = [[self SOMEDIRECTORY] stringByAppendingPathComponent:name];
BOOL success = [UIImageJPEGRepresentation(destImage, 0.9) writeToFile:thumbnailFilePath atomically:NO];
return success;
}
试试facebook的异步显示库。
https://github.com/facebook/AsyncDisplayKit
真的很容易使用..来自他们的指南: http : //asyncdisplaykit.org/guide/
_imageNode = [[ASImageNode alloc] init];
_imageNode.backgroundColor = [UIColor lightGrayColor];
_imageNode.image = [UIImage imageNamed:@"hello"];
_imageNode.frame = CGRectMake(10.0f, 10.0f, 40.0f, 40.0f);
[self.view addSubview:_imageNode.view];
这会在后台线程上解码图像。
我不确定在Xamarin上使用iOS库是否容易,但是如果它很容易,请试一试。
我将Paul Hegarty的CoreDataTableViewController子类化,并在CoreDataTableView中使用我的照片的缩略图。
在第14讲标题为FlickrFetcher和Photomania的示例中查找 。 您还需要在同一链接下载CoreDataTableViewController。
使用适当的标题创建CoreData实体,并定义所需的任何属性(数据变量)。 您需要定义两个“可转换”属性,一个用于照片,另一个用于缩略图。
然后在CoreDataTableView中加载缩略图:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{NSArray * exceptions = [NSArray arrayWithObjects:@“SCR”,@“DNS”,@“NT”,@“ND”,@“NH”,nil];
static NSString *CellIdentifier = @"resultsDisplayCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
MarksFromMeets *athleteMarks = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSString* date = [ITrackHelperMethods dateToAbbreviatedString:athleteMarks.meetDate];
NSMutableString *title = [NSMutableString stringWithFormat:@"%@", athleteMarks.markInEvent];
NSMutableString *subTitle = [NSMutableString stringWithFormat:@"%@ - %@",date, athleteMarks.meetName];
[title replaceOccurrencesOfString:@"(null)"
withString:@""
options:0
range:NSMakeRange(0, [title length])];
// cell.imageView.image = athleteMarks.photoThumbNail; // Don't like image in front of record.
[cell.textLabel setFont:[UIFont
fontWithName:@"Helvetica Neue" size:18]];
[cell.detailTextLabel setFont:[UIFont fontWithName:@"Helvetica Neue" size:16]];
[cell.detailTextLabel setTextColor:[UIColor grayColor]];
// make selected items orange
if ([athleteMarks.eventPR integerValue] != 0
&& (![exceptions containsObject:athleteMarks.markInEvent])) {
title = [NSMutableString stringWithFormat:@"%@ (PR)",title];
[cell.textLabel setTextColor:[UIColor redColor]];
}
else if ([athleteMarks.eventSB integerValue] != 0
&& (![exceptions containsObject:athleteMarks.markInEvent])) {
title = [NSMutableString stringWithFormat:@"%@ (SB)",title];
[cell.textLabel setTextColor:[UIColor orangeColor]];
} else {
[cell.textLabel setTextColor:[UIColor grayColor]];
}
cell.textLabel.text = title;
cell.detailTextLabel.text = subTitle;
cell.indentationLevel = indentationLevelOne;
cell.indentationWidth = indentationForCell;
return cell;
}
如果需要,我可以向您发送实体的NSManagedObject子类的类别示例。 此类别将照片和缩略图加载到CoreData实体中。 第一次会很慢。 但是,之后用户应该能够平滑地滚动TableView,然后所有更新的结果将自动加载。 让我知道。
一个好处是CoreData处理所有内存管理。
祝好运!
我没有足够的代表发表评论,所以这里的答案有助于我的tableview滚动性能:
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
这两个技巧让我的桌子流得非常好。 我从API服务获取图像数据,AFNETWORKING有一个很棒的图像加载器,但由于图像在捆绑中,所以不需要。
也许你可以试试SDWebImage
。 它也是一个xamarin 组件 ,它通过自动缓存到期处理来简化异步映像下载器和异步内存以及磁盘映像缓存。 使用它可能意味着丢弃大量硬编写的代码,但它可能是值得的 - 你的代码将变得更加简单。 在iOS中,您还可以在控制器的viewDidLoad中设置SDWebImageManager
:
- (void)viewDidLoad{
...
SDWebImageManager *manager = [SDWebImageManager sharedManager];
manager.delegate = self;
...
}
并将视图控制器设置为委托。 然后,当调用以下委托方法时:
- (UIImage *)imageManager:(SDWebImageManager *)imageManager transformDownloadedImage:(UIImage *)image withURL:(NSURL *)imageURL
您可以在缓存之前将图像缩放到适当大小的拇指。
希望有所帮助。
Weel我有类似的问题,我的卷轴不顺畅。 我在表中插入一个带有内部labelViews的变量UIImageView。 我所做的是为estimatedHeightforRowAtIndexPath更改方法HeightforRowAtIndexPath,现在滚动是平滑的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.