次のようなscrollViewで遅延読み込みを実行しました。
-(void)scrollViewDidScroll:(UIScrollView *)myScrollView {
int currentPage = (1 + myScrollView.contentOffset.x / kXItemSpacingIphone);
for (ItemView* itemView in [self.itemRow subviews]){
if (itemView.tag >= currentPage-2 && itemView.tag <= currentPage+2)
{
//keep it visible
if (!itemView.isLoaded) {
[itemView layoutWithData:[self.items objectAtIndex:itemView.tag-1]];
}
}
else
{
//hide it
if (itemView.isLoaded) {
[itemView unloadData];
}
}
}
}
基本的に、画面に表示されてから+/-2「ページ」の場合にビューをロードします。これにより、(一度に20以上のItemViewをロードする代わりに)使用しているメモリの量が大幅に削減されます。これは良いことです。ただし、すべてのロード/アンロードにより、特に低速のデバイスではスクロールが少し途切れます。ItemViewの読み込みで実際に起こっていることは次のとおりです。
- (void)layoutWithData:(Item*)_data {
self.data = _data;
//grab the image from the bundle
UIImage *img;
NSString *filePath = [[NSBundle mainBundle] pathForResource:_data.image ofType:@"jpg"];
if(filePath.length > 0 && filePath != (id)[NSNull null]) {
img = [UIImage imageWithContentsOfFile:filePath];
}
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setImage:img forState:UIControlStateNormal];
[btn addTarget:self action:@selector(tapDetected:) forControlEvents:UIControlEventTouchUpInside];
btn.frame = CGRectMake(0, 0, kItemPosterWidthIphone, kItemPosterHeightIphone);
[self addSubview:btn];
self.isLoaded = YES;
}
そして、ItemViewのアンロード:
- (void)unloadData{
for(UIView *subview in [self subviews]) {
[subview removeFromSuperview];
}
self.data = nil;
self.isLoaded = NO;
}
繰り返しますが、ロード/アンロードを高速化し、UIScrollViewをよりスムーズにするために何ができますか?
非同期の試行:
- (void)layoutWithData:(Item*)_data {
self.data = _data;
self.isLoaded = YES;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
UIImage *img;
NSString *filePath = [[NSBundle mainBundle] pathForResource:_data.image ofType:@"jpg"];
if(filePath.length > 0 && filePath != (id)[NSNull null]) {
img = [UIImage imageWithContentsOfFile:filePath];
}
dispatch_async(dispatch_get_main_queue(), ^{
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setImage:img forState:UIControlStateNormal];
[btn addTarget:self action:@selector(tapDetected:) forControlEvents:UIControlEventTouchUpInside];
btn.frame = CGRectMake(0, 0, kItemPosterWidthIphone, kItemPosterHeightIphone);
self.imageView = btn;
[self addSubview:btn];
});
});
}