前言

这里说的内容复用,是指添加到 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 < ) {
firstIndex = ;
}
if (lastIndex >= self.arrayQuestin.count) {
lastIndex = (self.arrayQuestin.count - );
}
// 回收掉不在显示的
NSInteger viewIndex = ;
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;//
CGRect vcFrame = bounds;
vcFrame.origin.x = CGRectGetWidth(bounds) * index;
vc.rectView = vcFrame;
vc.index = index;
vc.view.frame = vcFrame; // 最后在这个地方,更新模板VC中的信息
///更新信息处理
}

iOS-UIScrollView内容复用【实现两个试图的复用】的更多相关文章

  1. iOS UIScrollView的使用

    一.为什么要用UIScrollView? 移动设备的屏幕大小是极其有限的,因此直接展示在用户眼前的内容也相当有限当展示的内容较多,超出一个屏幕时,用户可通过滚动手势来查看屏幕以外的内容普通的UIVie ...

  2. 分列:将excel单元格的内容拆分为两列

    提要:处理excel数据时有时需要把单元格的内容拆分为两列,可能方便外部软件的链接,可能使数据显示更明晰等等,有人说直接剪切加粘贴不就可以了吗,但是有时数据过多,这样处理很不效率,网上搜索的方法说插入 ...

  3. iOS开发UI篇—推荐两个好用的Xcode插件(提供下载链接)

    iOS开发UI篇—推荐两个好用的Xcode插件(提供下载链接) 这里推荐两款好用的Xcode插件,并提供下载链接. 一.插件和使用如下: 1.两款插件 对项目中图片提供自动提示功能的插件:KSImag ...

  4. IOS UIScrollView常用代理方法

    iOS UIScrollView代理方法有很多,从头文件中找出来学习一下 //只要滚动了就会触发 - (void)scrollViewDidScroll:(UIScrollView *)scrollV ...

  5. iOS --UIScrollView的学习(一)

    1.为什么使用UIScrollView 因为移动设备的屏幕大小是极其有限的,因此直接展示在用户眼前的内容也相当有限,当展示的内容较多,超出一个屏幕时,用户可通过滚动手势来查看屏幕以外的内容普通的UIV ...

  6. 李洪强iOS经典面试题34-求两个链表表示的数的和

    李洪强iOS经典面试题34-求两个链表表示的数的和 问题 给你两个链表,分别表示两个非负的整数.每个链表的节点表示一个整数位. 为了方便计算,整数的低位在链表头,例如:123 在链表中的表示方式是: ...

  7. JS判断是IOS还是Android以及如何解决h5打包后在ios下内容与状态栏重叠问题

    h5打包后在ios下内容与状态栏重叠问题: 1:知道设备的类型: var u = navigator.userAgent, app = navigator.appVersion; var isAndr ...

  8. [iOS]UIScrollView嵌套内容在左右拨动的时候自动被顶上问题

    遇到的问题是这样的: 适配6+没问题,但是5s就出问题.我UIScrollView嵌套了左侧UIScrollView,右侧UITableView,左右拨动切换,结果5s下拨动之后两边的View都会自动 ...

  9. iOS 判断内容是否是中文,两种实现

    用category实现 新建类别文件,代码 .h文件 #import <Foundation/Foundation.h> @interface NSString (Valid) - (BO ...

随机推荐

  1. 8.15 自定义tr行 滚动 信息行的滚动

    <table class="zixun-con-table"> <tr class="hover"> <th style=&quo ...

  2. 创建WRAPPER时, SQL20076N 未对指定的操作启用数据库的实例。

    您可以通过运行DB2 UPDATE DBM CFG USING FEDERATED YES来设置这个参数.修改这个参数后,必须重新启动实例才会生效(DB2STOP/DB2START).所以你会出现你的 ...

  3. KOBAS

    1. What is KOBAS 3.0? KOBAS (KEGG Orthology Based Annotation System) is a web server for gene/protei ...

  4. Warning: Attempt to present A on B whose view is not in the window hierarchy!

    昨天写豆瓣发广播Demo的时候,为了写Demo的简单,就使用了Storyboard,结果执行视图跳转时遇到了这个问题: Warning: Attempt to present <UINaviga ...

  5. 命名空间namespace ,以及重复定义的问题解析

    名字空间是用来划分冲突域的,把全局名字空间划分成几个小的名字空间.全局函数,全局变量,以及类的名字是在同一个全局名字空间中,有时为了防止命名冲突,会把这些名字放到不同的名字空间中去. 首先我们看一下名 ...

  6. 551. Student Attendance Record I

    static int wing=[]() { std::ios::sync_with_stdio(false); cin.tie(NULL); ; }(); class Solution { publ ...

  7. 2018.07.01 洛谷小B的询问(莫队)

    P2709 小B的询问 题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数 ...

  8. Apache Struts 2 Documentation Big Picture

    http://struts.apache.org/docs/big-picture.html 1. HttpServletRequest 穿越各个过滤器到达FilterDispatcher(这个已经不 ...

  9. Yarn application has already exited with state FINISHED

    如果在运行spark-sql时遇到如下这样的错误,可能是因为yarn-site.xml中的配置项yarn.nodemanager.vmem-pmem-ratio值偏小,它的默认值为2.1,可以尝试改大 ...

  10. 使用idea,springboot,springsession,redis实现分布式微服务的session 共享

    本次开发环境:idea2016.3.4 +jdk1.8+maven3.3.9+redis+springboot+jedis 本文中的项目使用Maven来管理项目依赖,使用Spring Session和 ...