需求加载一个 UIScrollView
Posted
技术标签:
【中文标题】需求加载一个 UIScrollView【英文标题】:Demand loading a UIScrollView 【发布时间】:2012-05-14 02:50:27 【问题描述】:我想使用带有分页的 UIScrollView 实现一个应用,类似于苹果天气应用。
但我有点担心性能。我一直在使用的示例实现加载所有视图,然后应用程序启动。在某一点之后,一旦证明这很慢?
我想知道 Apple 的相机胶卷是如何处理这个问题的,用户可能有 100 多张可以滚动浏览的照片。我是否应该尝试找出一种仅在需要时才构建视图的方法?或者也许有一种方法可以从 UITableView 复制出列可重用单元格技术,仅用于水平视图加载,因为每个视图将具有相同的布局。
【问题讨论】:
【参考方案1】:到目前为止,最有效的解决方案(这在许多照片浏览应用程序中使用,例如 Facebook,也可能是本地照片应用程序)将是按需加载内容,就像 UITableView 所做的那样。 Apple 的 StreetScroller 示例项目应该让您走上正轨。
【讨论】:
我在页面控制演示developer.apple.com/library/ios/#samplecode/PageControl/…987654322@上建模了我的实现【参考方案2】:一个非常有效的解决方案是确保尽可能重用任何视图。如果您只想显示图像,则可以使用 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 类更新此内容时可能创建的任何拼写错误,我深表歉意。
【讨论】:
以上是关于需求加载一个 UIScrollView的主要内容,如果未能解决你的问题,请参考以下文章