前言
這里說的內容復用,是指添加到 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中的信息 ///更新信息處理
}