Ios 按需加载UIScrollView
我想实现一个应用程序,使用带分页的UIScrollView,类似于apple weather应用程序 但我有点担心表现。我使用的示例实现加载所有视图,然后应用程序启动。在某一点之后,一旦这证明是缓慢的Ios 按需加载UIScrollView,ios,cocoa-touch,uiscrollview,uipagecontrol,Ios,Cocoa Touch,Uiscrollview,Uipagecontrol,我想实现一个应用程序,使用带分页的UIScrollView,类似于apple weather应用程序 但我有点担心表现。我使用的示例实现加载所有视图,然后应用程序启动。在某一点之后,一旦这证明是缓慢的 我想知道苹果公司的相机卷是如何处理这个问题的,一个用户可能有100多张照片可以滚动浏览。我是否应该尝试找出一种仅在需要时构建视图的方法?或者有一种方法可以从UITableView中复制出队列可重用单元技术,仅用于水平视图加载,因为每个视图都具有相同的布局。目前为止,这是最有效的解决方案(这在许多照
我想知道苹果公司的相机卷是如何处理这个问题的,一个用户可能有100多张照片可以滚动浏览。我是否应该尝试找出一种仅在需要时构建视图的方法?或者有一种方法可以从UITableView中复制出队列可重用单元技术,仅用于水平视图加载,因为每个视图都具有相同的布局。目前为止,这是最有效的解决方案(这在许多照片浏览应用程序中使用,例如Facebook,也可能在本机照片应用程序中使用)将按需加载内容,就像UITableView一样。苹果的示例项目应该会让您走上正确的道路。一个非常有效的解决方案是确保尽可能重用任何视图。如果要简单地显示图像,可以使用UIScrollView的子类,并在LayoutSubView中布局这些可重用视图。在这里,您可以检测哪些视图可见,哪些视图不可见,并根据需要创建子视图 一个示例性的出列函数可能如下所示:
- (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。然后,您可以使用它来加载、获取任何当前屏幕外的图像视图,并快速、轻松地将它们恢复到视图中
您的布局子视图可能类似于:
- (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;
}
-(无效)布局子视图{
[超级布局子视图];
CGRect visibleBounds=[自边界];
CGPoint contentArea=[self contentOffset];
//回收所有不可见的瓷砖
对于(GSVLineTileView*在[自身子视图]中平铺){
如果(!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(行lastDisplayedColumn)
{
UImageView*tile=[自出队列可重用TileWithFrame:CGRectMake(tileSize.width*列,tileSize.height*行,tileSize.width,tileSize.height)和图像:YourImage];
[自添加子视图:平铺];
}
++上校;
}
++行;
}
firstDisplayedColumn=firstVisibleColumn;
lastDisplayedColumn=lastVisibleColumn;
firstDisplayedRow=firstVisibleRow;
lastDisplayedRow=lastVisibleRow;
}
当我在处理超大面积的滚动视图时,我使用了类似于此的方法在线条区域中平铺,它似乎工作得很好。很抱歉,在为图像视图而不是我的自定义tileView类更新时,我可能会造成任何键入错误。我在页面控件演示中对我的实现进行了建模