非常に効率的な解決策は、可能な限りビューを再利用することです。単に画像を表示する場合は、UIScrollViewのサブクラスを使用して、これらの再利用可能なビューをlayoutSubviews内にレイアウトできます。ここでは、表示されているビューと表示されていないビューを検出し、必要に応じてサブビューを作成できます。
デキュー関数の例は次のようになります。
- (UIImageView *)dequeueReusableTileWithFrame:(CGRect) frame andImage:(UIImage *) image
{
UIImageView *tile = [reusableTiles anyObject];
if (tile) {
[reusableTiles removeObject:tile];
tile.frame = frame;
}
else {
tile = [[UIImageView alloc] initWithFrame:frame];
}
tile.image = image;
return tile;
}
reusableTilesは、NSMutableSetタイプのiVarにすぎません。次に、これを使用して、現在オフスクリーンの画像ビューをロードフェッチし、すばやく簡単にビューに戻すことができます。
layoutSubviewsは次のようになります。
- (void)layoutSubviews {
[super layoutSubviews];
CGRect visibleBounds = [self bounds];
CGPoint contentArea = [self contentOffset];
//recycle all tiles that are not visible
for (GSVLineTileView *tile in [self subviews]) {
if (! CGRectIntersectsRect([tile frame], visibleBounds)) {
[reusableTiles addObject:tile];
[tile removeFromSuperview];
}
}
int col = firstVisibleColumn = floorf(CGRectGetMinX(visibleBounds)/tileSize.width);
lastVisibleColumn = floorf(CGRectGetMaxX(visibleBounds)/tileSize.width) ;
int row = firstVisibleRow = floorf(CGRectGetMinY(visibleBounds)/tileSize.height);
lastVisibleRow = floorf(CGRectGetMaxY(visibleBounds)/tileSize.height);
while(row <= lastVisibleRow)
{
col = firstVisibleColumn;
while (col <= lastVisibleColumn)
{
if(row < firstDisplayedRow || row > lastDisplayedRow || col < firstDisplayedColumn || col >lastDisplayedColumn)
{
UImageView* tile = [self dequeueReusableTileWithFrame:CGRectMake(tileSize.width*col, tileSize.height*row, tileSize.width, tileSize.height) andImage:YourImage];
[self addSubview:tile];
}
++col;
}
++row;
}
firstDisplayedColumn = firstVisibleColumn;
lastDisplayedColumn = lastVisibleColumn;
firstDisplayedRow = firstVisibleRow;
lastDisplayedRow = lastVisibleRow;
}
スクロールビューの非常に広い領域で作業しているときに、これに似たものを使用して線の領域を並べて表示しましたが、非常にうまく機能しているように見えました。カスタムtileViewクラスではなく画像ビュー用にこれを更新するときに作成したタイプミスについては申し訳ありません。