iOS-UIScrollView内容复用【实现两个试图的复用】

前言

这里说的内容复用,是指添加到 ScrollView 里面的试图是同一个模型;比如,我需要在 ScrollView 上从添加100个 xkVIew(其他封装好的VC、UIView),每次滑动 ScrollView 时,只需要更新 xkVIew 上的内容就行;ScrollView内容较多的情况下,可以考虑复用。

最近做试卷排版,在做试卷展示时,我封装好了一个基于VC的试题模型PaperQuestionViewController(用于显示每道试题的内容,模板里要加index 索引属性,便于复用),因为一套试卷,会有100+ 道试题,如果一下子把100+ 个试图同时添加到ScrollView上,那样内存比较大,这是复用最重要的原因;

实现

当前VC.m

///所有试题数组
@property (nonatomic,strong) NSArray *arrayQuestin;

///UIScrollView
@property (nonatomic,strong) UIScrollView *scrollview;

///保存可见的视图
@property (nonatomic, strong) NSMutableSet *visibleViewControllers;

/// 保存可重用的
@property (nonatomic, strong) NSMutableSet *reusedViewControllers;

引用ScrollView 代理

<UIScrollViewDelegate>

实现代理方法

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    ///更新模板信息
    [self showVc];
}

附加方法

///显示试图
- (void)showVc{
    // 获取当前处于显示范围的 控制器 索引
    CGRect visibleBounds = self.scrollview.bounds;
    CGFloat minX  = CGRectGetMinX(visibleBounds);
    CGFloat maxX  = CGRectGetMaxX(visibleBounds);
    CGFloat width = CGRectGetWidth(visibleBounds);
    NSInteger firstIndex = (NSInteger)floorf(minX / width);
    NSInteger lastIndex  = (NSInteger)floorf(maxX / width);
    
    // 处理越界
    if (firstIndex < 0) {
        firstIndex = 0;
    }
    if (lastIndex >= self.arrayQuestin.count) {
        lastIndex = (self.arrayQuestin.count - 1);
    }
    // 回收不在显示 的
    NSInteger viewIndex = 0;
    for (PaperQuestionViewController * vc in self.visibleViewControllers) {
        viewIndex = vc.index;
        // 不在显示范围内
        if ( viewIndex < firstIndex || viewIndex > lastIndex) {
            [self.reusedViewControllers addObject:vc];
            [vc removeFromParentViewController];
            [vc.view removeFromSuperview];
        }
    }
    [self.visibleViewControllers minusSet:self.reusedViewControllers];
    // 是否需要显示新的视图
    for (NSInteger index = firstIndex; index <= lastIndex; index ++) {
        BOOL isShow = NO;
        for (BookPaperQuestionViewController * childVc in self.visibleViewControllers) {
            
            if (childVc.index == index) {
                isShow = YES;
            }
        }
        if (!isShow ) {
            [self showVcWithIndex:index];
        }
    }
}

// 显示一个 view
- (void)showVcWithIndex:(NSInteger)index{
    PaperQuestionViewController *vc = [self.reusedViewControllers anyObject];
    if (vc) {
        [self.reusedViewControllers removeObject:vc];
        
    }else{
        PaperQuestionViewController *childVc = [[PaperQuestionViewController alloc] init];
        [self addChildViewController:childVc];
        vc = childVc;
    }
    CGRect bounds  = self.scrollview.bounds;//654
    CGRect vcFrame = bounds;
    vcFrame.origin.x = CGRectGetWidth(bounds) * index;
    vc.rectView = vcFrame;
    vc.index = index;
    vc.view.frame = vcFrame;
   
    // 最后在这个地方,更新模板VC中的信息
    ///更新信息处理
 }

引用:https://www.imooc.com/article/1065