滚动视图性能优化的几种方式

目的:

  - 我们每次发布IOS时都会有一些新特性页面,当然还有广告条都会用到滚动视图。那么如何性能优化呢?目前就我所知有两种方案,一种就是常用的2-3张图片重复利用,另一种就是今天主要讲的利用UICollectionView来做。

  - 今天就做一个新特性页面为例

步骤:

  方法一:利用UICollectionView

1.UICollectionView继承UIScrollView,我们要用滚动视图,肯定会用到ScrollView,而如何我们把collectionView中的一个Item当作滚动视图一页来做是否可行呢?

2.创建UICollectionView有一个注意点,就是创建的时候必须要创建一个layout,代码如下

- (instancetype)init
{
    
    UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
    
    
    // 设置滚动方向
    layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
    
    // 设置同一行的item间隔
    layout.minimumInteritemSpacing = 0;
    // 设置行之间的间隔
    layout.minimumLineSpacing = 0;
    
    // 设置单个item的大小
    layout.itemSize = SAMScreenBounds.size;
    
    return [super initWithCollectionViewLayout:layout];
    
}

3、下面要思考的就是CollectionView的Cell本身并没有image,这时我们就应该考虑自定义Cell,创建Cell让继承UICollectionViewCell

// 实现懒加载
- (UIImageView *)imageView
{
    if (_imageView == nil) {
        UIImageView *imV = [[UIImageView alloc] initWithFrame:self.bounds];
        _imageView = imV;
        [self.contentView addSubview:_imageView];
    }
    return _imageView;
}

- (void)setImage:(UIImage *)image
{
    _image = image;
    
    self.imageView.image = image;
}

4.完成数据源协议,基本跟tableView差不多,在此就不多说了,至于为什么用uicollectionView因为省去了性能优化,直接让苹果帮我们做了,下面我会验证。

5.至此一个简单的滚动视图告一段落了!

  方法二:利用2张图片重复利用实现无限滚动

底层思想:

  - 2张图片重复利用的底层思想就是ScrollView的contentSize是三倍的ScrollView的宽度(或者高度,取决于滚动方向),2张图片一张用于显示(visibleView),另一张用于重复利用(reuseView),总是让显示的那张位于ScrollView的滚动范围中间页,如果到两边每次滚动结束就和重利用的滚动位置交换。而重利用的图片控件就是专门用来显示下一张要滚动的视图(在滚动结束前)。

- (void)viewDidLoad {
    [super viewDidLoad];
   
    self.scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
    
    // 添加ScrollView并设置
    _scrollView.contentSize = CGSizeMake(3 * kWidth, 0);
    _scrollView.contentOffset = CGPointMake(kWidth , 0);
    _scrollView.showsHorizontalScrollIndicator = NO;
    _scrollView.bounces = NO;
    _scrollView.delegate = self;
    _scrollView.pagingEnabled = YES;
    [self.view addSubview:_scrollView];
    
    // 添加可见的imageView
    _visibleView = [[UIImageView alloc] initWithFrame:CGRectMake(kWidth, 0, kWidth, kHeight)];
    _visibleView.tag = 0;
    _visibleView.image = [UIImage imageNamed:@"00"];
    [_scrollView addSubview:_visibleView];
    
    //添加重复利用的imageView
    _reuseView = [[UIImageView alloc] init];
    _reuseView.frame = self.view.bounds;
    [_scrollView addSubview:_reuseView];

}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    CGRect frame = _reuseView.frame;
    CGFloat offsetX = self.scrollView.contentOffset.x;
    int index = 0;
    
    // 判断最左 或 最右边
    if (offsetX > _visibleView.frame.origin.x) { // 最右
        
        frame.origin.x = _scrollView.contentSize.width - kWidth;
        
        /**
         *  这边只是利用tag来获取哪一个图片,要确保不能第一次滚动都+1,必须要要换取位置之后再加1
         */
        index = (int)_visibleView.tag + 1;
        
        //超过最大数目,这样就重置
        if (index == kCount) { // 最左
            index = 0;
        }
    }else{
        frame.origin.x = 0;
        index = (int)_visibleView.tag - 1;
        if (index < 0) {
            index = kCount - 1;
        }
    }
    
    // 赋值给reuseView方便交换给visibleView
    _reuseView.tag = index;
    // 让重利用视图加在将要出现的位置
    _reuseView.frame = frame;
    _reuseView.image = [UIImage imageNamed:[NSString stringWithFormat:@"0%d",index]];
    
    /**
     * 1.滚动结束后交换位置
     * 2.让可见视图出现在中间位置
     * 3.改变contentOffset正好让可见视图出现在屏幕中
     */
    if (offsetX <= 0 || offsetX >= kWidth  * 2) {
        UIImageView *stmpView = _visibleView;
        _visibleView = _reuseView;
        _reuseView = stmpView;
        
        _visibleView.frame = _reuseView.frame;
        
        self.scrollView.contentOffset = CGPointMake(kWidth, 0);
    }
    
    
    
}

原文地址:https://www.cnblogs.com/samyangldora/p/4611935.html