我已经实现了一个带分页的scrollview,可以在整个页面(如iPhone中安装的Photo应用程序)之间滚动一些图像(图形)。
我发现下面的代码使用了经典的3页解决方案(我对我的应用程序进行了一些小修改)但是,即使它“有效”,滚动似乎很慢并且经常在我滚动一些图像之后应用程序崩溃。
我正在使用启用了ARC选项的Xcode 4.2并在iPad设备上进行测试。 图像(10 jpg)为2048x1539,平均尺寸为200 / 250Kb。
有没有人可以帮助我找到问题的原因?
谢谢, 的Corrado
const int numImages = 10;
const float kPageWidth = 1024.0f;
const float kPageHeight = 768.0f;
- (void)viewDidLoad {
[super viewDidLoad];
scroll.contentSize = CGSizeMake(kPageWidth * numImages, kPageHeight);
imageview1 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, kPageWidth, kPageHeight)];
imageview2 = [[UIImageView alloc] initWithFrame:CGRectMake(kPageWidth, 0, kPageWidth, kPageHeight)];
imageview3 = [[UIImageView alloc] initWithFrame:CGRectMake(kPageWidth * 2, 0, kPageWidth, kPageHeight)];
scroll.contentOffset = CGPointMake(0, 0);
[imageview1 setImage:[UIImage imageNamed:@"grafico_0.jpg"]];
imageview1.contentMode = UIViewContentModeScaleAspectFit;
[imageview1 setTag:1];
imageview2.contentMode = UIViewContentModeScaleAspectFit;
[imageview2 setTag:2];
imageview3.contentMode = UIViewContentModeScaleAspectFit;
[imageview3 setTag:3];
[scroll addSubview:imageview1];
[scroll addSubview:imageview2];
[scroll addSubview:imageview3];
}
- (void)scrollViewDidScroll:(UIScrollView*)scrollView {
const CGFloat currPos = scrollView.contentOffset.x;
const NSInteger selectedPage = lroundf(currPos * (1.0f / kPageWidth));
const NSInteger zone = 1 + (selectedPage % 3);
const NSInteger nextPage = selectedPage + 1;
const NSInteger prevPage = selectedPage - 1;
/// Next page
if (nextPage < numImages)
{
NSInteger nextViewTag = zone + 1;
if (nextViewTag == 4)
nextViewTag = 1;
UIImageView* nextView = (UIImageView*)[scrollView viewWithTag:nextViewTag];
nextView.frame = (CGRect){.origin.x = nextPage * kPageHeight, .origin.y = 0.0f, kPageHeight, kPageWidth};
NSString *str = [NSString stringWithFormat:@"grafico_%d.jpg", nextPage];
UIImage* img = [UIImage imageNamed:str];
nextView.image = img;
}
/// Prev page
if (prevPage >= 0)
{
NSInteger prevViewTag = zone - 1;
if (!prevViewTag)
prevViewTag = 3;
UIImageView* prevView = (UIImageView*)[scrollView viewWithTag:prevViewTag];
prevView.frame = (CGRect){.origin.x = prevPage * kPageHeight, .origin.y = 0.0f, kPageHeight, kPageWidth};
NSString *str = [NSString stringWithFormat:@"grafico_%d.jpg", prevPage];
UIImage* img = [UIImage imageNamed:str];
prevView.image = img;
}
}
答案 0 :(得分:1)
您不应该使用imageNamed:
来加载大图像,因为该方法会缓存图像,并且只能用于您在应用中多次使用的小图像(如按钮的图像等) 。该方法因与许多大图像一起使用而导致内存问题而臭名昭着。
转而使用imageWithContentsOfFile:
。使用该方法加载图像可确保不再缓存图像,并且在不再使用图像后释放内存。
如果滚动似乎缓慢,您可以使用performSelectorInBackground
将图像加载到后台线程:
[self performSelectorInBackground:@selector(retrieveImageData:) withObject:imagePath];
在这种方法中加载UIImage:
- (void)retrieveImageData:(NSString *)imagePath {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
[self performSelectorOnMainThread:@selector(imageDataRetrieved:) withObject:image waitUntilDone:NO];
[pool release];
}
并将图像附加到主线程上的UIImageView(UI操作不得在后台线程上发生):
- (void)imageDataRetrieved:(UIImage)*image {
yourImageView.image = image;
}