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中的信息
///更新信息处理
}
分类:
iOS笔记
标签:
scrollview
, 电子书
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】