我正在一个项目( iOS7& ARC )中,我想在滚动视图中显示 N数的图像。这些图像已经存储进入沙箱目录。我的应用只有横向我遇到的问题是 ScrollView不流畅,滚动2-3次后卡住
这是我配置ScrollView
[self.containerScroll setAutoresizesSubviews:NO];
self.containerScroll.pagingEnabled = YES;
self.containerScroll.showsHorizontalScrollIndicator = NO;
self.containerScroll.showsVerticalScrollIndicator = NO;
self.containerScroll.scrollsToTop = NO;
self.containerScroll.maximumZoomScale = 5.0;
self.containerScroll.minimumZoomScale = 1.0;
self.containerScroll.delegate = self;
我一次只在scrollView
中保留三张图片。
我正在以{方法
中的ScrollView
加载图片
-(void) loadScrollViewWithPage:(int) page{
if (page >= self.numberOfSlides)
return;
float image_width;
float image_height;
if(self.isFromListView){
if(IS_IPHONE5){
image_width = 568.0f;
image_height = 320.0f;
} else{
// iPhone retina-3.5 inch
image_width = 480.0f;
image_height = 320.0f;
}
}
else{
image_width = IMAGE_WIDTH;
image_height = IMAGE_HEIGHT;
}
CGFloat xPos = page * image_width;
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(xPos, 0.0f, image_width, image_height)];
imgView.tag = page;
NSString *imgPath = [self.storageDirPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%d%@", page, Image_Extension_JPG]];
NSFileManager *fileManager = [NSFileManager defaultManager];
__block UIImage *img = nil;
if(![fileManager fileExistsAtPath:imgPath]){
[imgView setContentMode:UIViewContentModeCenter];
img = [UIImage imageNamed:@"icon-loader.png"];
[imgView setImage:img];
}
else{
[imgView setContentMode:UIViewContentModeScaleAspectFit];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
img = [[UIImage alloc] initWithCGImage:[[UIImage imageWithData:[NSData dataWithContentsOfFile:imgPath]] CGImage] scale:1.0 orientation:UIImageOrientationUp];
dispatch_async(dispatch_get_main_queue(), ^{
[imgView setImage:img];
});
});
}
[self.containerScroll addSubview:imgView];
img = nil;
fileManager = nil;
imgView = nil;
}
以及我的ScrollView
委托方法如何...
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
self.containerScroll.scrollEnabled = YES;
float page = self.containerScroll.contentOffset.x/self.view.frame.size.width;
showingSlide = (UInt16) roundf(page);
if(scrollView == self.containerScroll){
// switch the indicator when more than 50% of the previous/next page is visible
CGFloat pageWidth = CGRectGetWidth(self.containerScroll.frame);
NSUInteger pageNo = floor((self.containerScroll.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
// load the visible page and the page on either side of it (to avoid flashes when the user starts scrolling)
[self loadScrollViewWithPage:pageNo - 1];
[self loadScrollViewWithPage:pageNo];
[self loadScrollViewWithPage:pageNo + 1];
// a possible optimization would be to unload the views+controllers which are no longer visible
if(scrollView == self.containerScroll)
{
[self.previewTableView reloadData];
[self.previewTableView setContentOffset:CGPointMake(0, (page*220)+64) animated:NO];
[self.previewTableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:page inSection:0] atScrollPosition:UITableViewScrollPositionMiddle animated:YES];
[self updateSlideNumber];
[self flashSlideNumber];
}
//unload unnecessary imageviews from scroll view
for (UIView* view in self.containerScroll.subviews) {
if ([view isKindOfClass:[UIImageView class]] && view.tag != page && view.tag != page-1 && view.tag != page+1) {
[view removeFromSuperview];
}
}
}
}
现在问题是scrollView
的平稳性。当我开始滚动它滚动很好但是在2或3之后(或任何随机数之后)页面滚动,它卡住并且在尝试2-3次之后它再次移动并且我必须用力轻扫以滚动。提前谢谢。
答案 0 :(得分:0)
我认为这是某个地方的内存问题在你的代码中尝试@autorelease pool。
答案 1 :(得分:0)
使用scrollview不是显示图像的好方法,我建议您使用tableview或collevtionview。
你的应用程序的内存将随着每个滚动而不断增加,因为scollview不会重用内存,另一方面tableview和collectionview会重用内存。
答案 2 :(得分:0)
作为变得更好的最有效方式,在监视应用程序中的内存使用情况时,滚动速度非常慢(一次一个)。当每个新图像添加到视图中时,您将能够观看它,特别是如果您尚未对图像进行任何优化。
另一件事是,虽然您的代码确实看起来像是取消分层图像,但您仍然需要记住它仍然需要在滚动时尝试重新加载图像。您正在主线程上创建图像,因此您永远无法获得UITableView的平滑度。虽然我意识到您正在异步线程上创建图像视图,但添加和滚动它们的行为仍然由主线程处理。
我建议使用UITableView来解决你的问题,或者建议使用UICollectionView。如果你开始使用滚动视图,我会建议使用某种类型的破碎机使图像尺寸尽可能小,同时保持质量不错。
如果您需要有关TableView实现的帮助,您应该找到有关SO的大量信息。如果你仍然希望它看起来像一个滚动视图,可能是一个很好的选择只是让所有的分隔符,标题等为零,然后只是使用延迟加载图像。
答案 3 :(得分:0)
你犯了两个错误。首先:永远不要将imageNamed用于非图形内容(例如,使用imageNamed作为按钮背景)。第二:你尝试实时加载大图像。所以你滚动视图因此有滞后。如果在显示滚动视图之前加载所有图像,则胺化结束滞后。但你可以得到记忆警告。所以,你需要优化它。附:对不起我的英文