优化——UIScrollView通过内容延迟加载以达到平滑滑动。

来源:互联网 发布:赤狐软件怎么样 编辑:程序博客网 时间:2024/05/23 20:15

前面写了一篇《UIScrollView 平滑划动处理》,是通过延迟操作来达到平滑移动,但操作起来比较生涩,而且逻辑较复杂,现在已经弃之不用。

前文已经提到,将所有的内容页全部加入到ScrollView是最简单的方法,而且能够非常平滑划动,但如果是大数据量的时候,明显是不适用的。最近参考了Three20的TTScrollView以及TTPhotoViewController后,终于找到了一种内容页延迟加载的方法,其实iOS设备上的照片浏览就是通过延迟加载的方式实现的,当你快速划动的时候,加载的是缩略图,然后再装入原图。

同样是三页轮转ScrollView.m:

       _scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.width, self.view.height)];    _scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;    _scrollView.backgroundColor = [UIColor clearColor];    _scrollView.contentSize = _scrollView.frame.size;    _scrollView.pagingEnabled = YES;    _scrollView.delegate = self;    [self.view addSubview:_scrollView];        CGRect scrollviewFrame = CGRectMake(0, 0, _scrollView.width, _scrollView.height);    _currentPageView = [[ContentView alloc] initWithFrame:scrollviewFrame];    _prevPageView = [[ContentView alloc] initWithFrame:scrollviewFrame];    _nextPageView = [[ContentView alloc] initWithFrame:scrollviewFrame];        [_scrollView addSubview:_prevPageView];    [_scrollView addSubview:_nextPageView];    [_scrollView addSubview:_currentPageView];        _prevPageView.autoresizingMask = _nextPageView.autoresizingMask =     _currentPageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;    

翻页过程中(scrollViewDidScroll),进行必要的即时更新,但这个更新操作必须尽量少,以免影响划动的平滑体验,如加载较小的缩略图。而在翻页后,再通过延时操作载入全部内容进行更新。这样处理后的体验就跟iOS设备上原生的照片App一样,快速划动载入的是缩略图,停顿后则延迟载入正常的图片。

//更新操作- (void)loadContentView:(ContentView *)contentView withPageIndex:(NSInteger)page isDelay:(BOOL)isDelay{    //判断越界    if ((_numberOfPages <= 0))    {        return;    }    Feed *feedData = nil;    if (page >= 0 && page < _feedDatas.count)    {        feedData = [_feedDatas objectAtIndex:page];    }    if (feedData != contentView.feedData)    {        //内容不一致,则调用延迟更新        [contentView loadContentWithFeed:feedData isDelay:isDelay];    }}#pragma mark -#pragma mark UIScrollView- (void)scrollViewDidScroll:(UIScrollView *)scrollView{    NSInteger page = floor((_scrollView.contentOffset.x - _scrollView.width / 2) / _scrollView.width) + 1;        if (_currentPageIndex == page || page > _numberOfPages - 1 || page < 0)    {        return;    }        //换页操作    ContentView *tempPageView = nil;    //next page    if (_currentPageIndex + 1 == page)    {                tempPageView = _currentPageView;        _currentPageView = _nextPageView;        _nextPageView = _prevPageView;        _prevPageView = tempPageView;        [_nextPageView clearContent];    }    //prev page    else if (_currentPageIndex - 1 == page)    {        tempPageView = _currentPageView;        _currentPageView = _prevPageView;        _prevPageView = _nextPageView;        _nextPageView = tempPageView;                [_prevPageView clearContent];    }        _currentPageIndex = page;    _currentPageView.left = _scrollView.width * _currentPageIndex;    _prevPageView.right = _currentPageView.left;    _nextPageView.left = _currentPageView.right;        //即时的更新,如载入缩略图等}- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{    if (!decelerate)    {        [self scrollViewDidEndDecelerating:scrollView];    }}- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{    //延迟更新操作,这里是调用每个页面的延迟更新操作    //这里的更新稍显复杂,如果每个页面只是UIImageView的话,则可直接通过NSTimer延迟载入内容    [self loadContentView:_currentPageView withPageIndex:_currentPageIndex isDelay:YES];    [self loadContentView:_nextPageView withPageIndex:(_currentPageIndex + 1) isDelay:YES];    [self loadContentView:_prevPageView withPageIndex:(_currentPageIndex - 1) isDelay:YES];}

而页面(ContentView )内部的延迟更新代码则为:

static const NSTimeInterval kContentLoadDelay = 0.5;- (void)loadContentBody{    //更新ContentView的延迟内容    //.......    [_activityIndicatorView stopAnimating];}- (void)loadContentDelayed {    _loadTimer = nil;    [self loadContentBody];}- (void)startContentLoadTimer:(NSTimeInterval)delay {    [_activityIndicatorView startAnimating];    [_loadTimer invalidate];    _loadTimer = [NSTimer scheduledTimerWithTimeInterval:delay                                                  target:self                                                selector:@selector(loadContentDelayed)                                                userInfo:nil                                                 repeats:NO];}- (void)loadContentWithFeed:(Feed *)feed isDelay:(BOOL)isDelay{    //content相同则退出    if (feed == self.feedData)    {        return;    }        //清空content(会同时清空feedData)后赋值    [self clearContent];        self.feedData = feed;    if (nil == self.feedData)    {        return;    }        [_activityIndicatorView startAnimating];    [self loadContentHeader];    if (isDelay)    {        //真正的延迟处理        [self startContentLoadTimer:kContentLoadDelay];    }    else    {        [self loadContentBody];    }}

代码示例:http://download.csdn.net/detail/gavinming/4058379
代码非常简单,很容易理解,如有更好的方法或者意见,欢迎指点。

原创粉丝点击