zoukankan      html  css  js  c++  java
  • iOS-UIScrollView内容复用【实现两个试图的复用】

    前言

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

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

    实现

    当前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中的信息
        ///更新信息处理
     }
  • 相关阅读:
    剑指offer-23.链表中环的入口节点
    剑指offer-6从尾到头打印链表
    剑指offer-24.反转链表
    2-常见机器学习模型总结
    1-预测分析类核心算法简介
    罗马数字转整数Leetcode13
    链表反转leetcode206
    LINUX常用命令
    两种遍历list
    python笔记-字符串函数总结
  • 原文地址:https://www.cnblogs.com/wangkejia/p/8818297.html
Copyright © 2011-2022 走看看