UIscrollView 的子视图复用

复用原理:

1.添加一个可视集合,一个重用集合;

@property (nonatomic, strong) NSMutableSet *visibleLabels;
@property (nonatomic, strong) NSMutableSet *reusedLabels;

2.刚开始创建单屏多N个的子视图(N=1,2,3都可以),这里我创建的是9+2=11个label

 for (int i=0; i<self.maxNumbersDotForX+2; i++) {
          [self showLabelAtIndex:i];
    }

3.创建的时候这里首先从重用集合中取,有就去掉取出的label,没有就创建,类似cell;
创建的时候再对label进行相关的个性设置,方法跟 cellForRowAtindexPath:类似

- (void)showLabelAtIndex:(NSInteger)index {
    
    JAYChartLabel *label = [self.reusedLabels anyObject];
    
    if (label) {
        [self.reusedLabels removeObject:label];
    } else {
        label = [[JAYChartLabel alloc] init];
        
    }
    
    CGRect labelFrame = CGRectMake(JAYYLabelwidth-_xLabelWidth*.5 +index * _xLabelWidth+_xLabelWidth*_flag, _myScrollView.frame.size.height-kBottomXLabelsH-JAYLabelHeight*0.5, _xLabelWidth, kBottomXLabelsH);
    
    label.frame=  labelFrame;
    label.tag = index;
    label.text =[self.labelNames objectAt:index];
    [self.visibleLabels addObject:label];
    [_myScrollView addSubview:label];
    
}

4.处理scrollView滑动时候的代理

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    
    [self showMoreLabels];
   }

5.处理滑动过程中的操作:(关键)

a.先获取当前scorllView的contentoffset,或者是bounds,即相比于最初滑动的偏移,找出偏移点即屏幕当前的可视范围;

b.计算可视范围的起始下标以及终止下标,要注意处理数组越界的问题;

c.遍历可视集合中的元素,把不在可视范围的元素添加到重用集合中,并把可视集合中所有在重用集合的元素删除;

d.判断新的在可视范围的下标,是否存在于可视数组中,若存在就不处理,不存在,即表示需要从重用集合中添加;并重新赋值;

- (void)showMoreLabels
{
    CGRect visibleBounds = _myScrollView.bounds;
    CGFloat minX = CGRectGetMinX(visibleBounds);
    CGFloat maxX = CGRectGetMaxX(visibleBounds);
    
    NSInteger firstIndex = (NSInteger)floorf((minX-JAYYLabelwidth)/_xLabelWidth);
    NSInteger lastIndex = (NSInteger)floorf((maxX-JAYYLabelwidth)/_xLabelWidth);

    if (firstIndex<0) {
        firstIndex = 0;
    }
    if (lastIndex>=[self.labelNames count]) {
        lastIndex = [self.labelNames count]-1;
    }
    /*回收不在范围的Label*/
    NSInteger labelIndex =0 ;
    for (JAYChartLabel *label in self.visibleLabels) {
        labelIndex = label.tag;
        if (labelIndex<firstIndex||labelIndex>lastIndex) {
            [self.reusedLabels addObject:label];
            [label removeFromSuperview];
        }
    }
    
    [self.visibleLabels minusSet:self.reusedLabels];
    /*判断是否在显示,没有显示则添加*/
    for (NSInteger index = firstIndex; index<=lastIndex; index++) {
        BOOL isShow = NO;
        for (JAYChartLabel *label in self.visibleLabels) {
            if (label.tag == index) {
                isShow = YES;
            }
        }
        if (!isShow) {
            [self showLabelAtIndex:index];
        }
        
    }

}
原文地址:https://www.cnblogs.com/jayzhang/p/5105090.html