首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >按需加载UIScrollView

按需加载UIScrollView
EN

Stack Overflow用户
提问于 2012-05-14 10:50:27
回答 2查看 2K关注 0票数 2

我想实现一个应用程序使用UIScrollView与分页,类似于苹果天气应用程序。

但我有点担心性能。我使用的示例实现加载了所有视图,然后应用程序启动。在某一点之后,一旦这被证明是缓慢的?

我想知道苹果的相机胶卷是如何处理这个问题的,用户可能会有可以滚动浏览的100+照片。我是否应该尝试找出一种仅在需要时才构建视图的方法?或者,也许有一种方法可以从UITableView复制出队可重用单元技术,仅用于水平视图加载,因为每个视图都将具有相同的布局。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-05-14 11:35:02

到目前为止,最有效的解决方案将是按需加载内容,就像UITableView一样。苹果的StreetScroller示例项目应该会让你走上正轨。

票数 4
EN

Stack Overflow用户

发布于 2012-05-14 12:19:03

一个非常有效的解决方案是确保尽可能重用任何视图。如果您打算简单地显示图像,您可以使用UIScrollView的子类,并在layoutSubviews中布局这些可重用的视图。在这里,您可以检测哪些视图是可见的,哪些视图是不可见的,并根据需要创建子视图。

出队函数示例可能如下所示:

代码语言:javascript
运行
复制
- (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可能如下所示:

代码语言:javascript
运行
复制
- (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类时可能造成的任何拼写错误,我深表歉意。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10577020

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档