iOS 简单易学的无线滚动,支持UIImageView、UIView

思路:UIScrollView上添加三个图层(UIImage无限滚动则添加三个UIImageView,UIView无限滚动则添加三个UIView),手动定义三个视图下标(下标用于获取数据源),中间视图下标初始定为0,左侧视图下标定为数据源数组最大下标(arr.count -1),右侧视图下标定为1。监测scroll滑动方法:右滑全体下标+1,判断三个下标等于arr.count时将下标赋为0;左滑全体下标-1,判断三个下标等于-1时将该下标赋为数据源数组最大下标(arr.count -1)。手动将scroll.offset设为中间视图的位置(不带滑动特效)。

UIImageView:

UIImageView和UIScrollView定义略

关键方法:

//这个方法会在子视图添加到父视图或者离开父视图时调用

- (void)willMoveToSuperview:(UIView*)newSuperview

{

    //解决当父View释放时,当前视图因为被Timer强引用而不能释放的问题

    if(!newSuperview)

    {

        [self.moveTimerinvalidate];

        moveTimer=nil;

    }

    else

    {

        [selfsetUpTime];

    }

}

- (void)setUpTime

{

    moveTimer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(animalMoveImage:) userInfo:nil repeats:YES];

    isTimeUp = NO;

}

- (void)animalMoveImage:(NSTimer*)time

{

    if(self.imageLinkURL.count<=1)

    {

        return;

    }

    [self setContentOffset:CGPointMake(SCREEN_WIDTH * 2, 0) animated:YES];

    isTimeUp = YES;

    [NSTimer scheduledTimerWithTimeInterval:0.3f target:self selector:@selector(scrollViewDidScroll:) userInfo:nil repeats:NO];

}

#pragma mark - 图片停止时,调用该函数使得滚动视图复用

- (void)scrollViewDidScroll:(UIScrollView*)scrollView

{

    if (self.contentOffset.x <= 0)

    {

        centerImageIndex = centerImageIndex - 1;

        leftImageIndex = leftImageIndex - 1;

        rightImageIndex = rightImageIndex - 1;


        if(leftImageIndex== -1) {

            leftImageIndex = _imageLinkURL.count-1;

        }

        if (centerImageIndex == -1)

        {

            centerImageIndex = _imageLinkURL.count-1;

        }

        if(rightImageIndex== -1)

        {

            rightImageIndex = _imageLinkURL.count-1;

        }

    }

    elseif(self.contentOffset.x>=SCREEN_WIDTH*2)

    {

        centerImageIndex = centerImageIndex + 1;

        leftImageIndex = leftImageIndex + 1;

        rightImageIndex = rightImageIndex + 1;


        if (leftImageIndex == _imageLinkURL.count) {

            leftImageIndex=0;

        }

        if (centerImageIndex == _imageLinkURL.count)

        {

            centerImageIndex = 0;

        }

        if (rightImageIndex == _imageLinkURL.count)

        {

            rightImageIndex=0;

        }

    }

    else

    {

        return;

    }


    _leftImageView  根据下标leftImageIndex使用图片显示框架进行图片显示

    _centerImageView 根据下标centerImageIndex使用图片显示框架进行图片显示

    _rightImageView 根据下标rightImageIndex使用图片显示框架进行图片显示

    self.contentOffset = CGPointMake(SCREEN_WIDTH, 0);


    //手动控制图片滚动应该取消那个三秒的计时器

    if(!isTimeUp) {

        [moveTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:3.0]];

    }

    isTimeUp = NO;

}

- (void)scrollViewWillBeginDragging:(UIScrollView*)scrollView

{

    [moveTimer invalidate];

    moveTimer = nil;

}

- (void)scrollViewDidEndDragging:(UIScrollView*)scrollView willDecelerate:(BOOL)decelerate

{

    [self setUpTime];

}

UIView:

此处以两个视图无限滚动为例,view无限滚动注意点:需要拷贝代码/xib生成的view,拷贝方法:对view的归档、解档。因使用归档/解档拷贝出来的view其子视图圆角等自定义属性会被格式化,此处笔者使用对子视图标记tag来进行二次设置。多次的归档/解档会占用一部分内存,所以只copy一次(数据源大于等于3时,三个view不存在相同的情况,只需要将view加入数组按下标取即可)

关键方法:

- (void)willMoveToSuperview:(UIView*)newSuperview

{

    if(!newSuperview)

    {

        [self.moveTimerinvalidate];

        moveTimer=nil;

    }

    else

    {

        [selfsetUpTime];

    }

}

- (void)setUpTime

{

    moveTimer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(animalMoveImage:) userInfo:nil repeats:YES];

    isTimeUp = NO;

}

- (void)animalMoveImage:(NSTimer*)time

{

    if(self.recommendViewArr.count <= 1)

    {

        return;

    }

    [self.scrollRecommend setContentOffset:CGPointMake(SCREEN_NEW_WIDTH * 2, 0) animated:YES];

    isTimeUp = YES;

    [NSTimer scheduledTimerWithTimeInterval:0.3f target:self selector:@selector(scrollViewDidScroll:) userInfo:nil repeats:NO];

}

- (void)scrollViewDidScroll:(UIScrollView*)scrollView

{

    if (self.scrollRecommend.contentOffset.x <= 0)

    {

        centerViewIndex = centerViewIndex - 1;

        leftViewIndex = leftViewIndex - 1;

        rightViewIndex = rightViewIndex - 1;


        if(leftViewIndex== -1) {

            leftViewIndex = self.recommendViewArr.count-1;

        }

        if(centerViewIndex== -1)

        {

            centerViewIndex = self.recommendViewArr.count-1;

        }

        if(rightViewIndex== -1)

        {

            rightViewIndex = self.recommendViewArr.count-1;

        }

    }

    elseif(self.scrollRecommend.contentOffset.x>= (SCREEN_NEW_WIDTH*2))

    {

        centerViewIndex = centerViewIndex + 1;

        leftViewIndex = leftViewIndex + 1;

        rightViewIndex = rightViewIndex + 1;


        if (leftViewIndex == self.recommendViewArr.count) {

            leftViewIndex=0;

        }

        if (centerViewIndex == self.recommendViewArr.count)

        {

            centerViewIndex=0;

        }

        if (rightViewIndex == self.recommendViewArr.count)

        {

            rightViewIndex=0;

        }

    }

    else

    {

        return;

    }


    //view不能同时拥有两个父视图,所以_viewHotelRecommend和_viewIntegralRecommend在_leftView和_centerView中切换不需要先进行移除操作,重复addSubview中会进行切断旧父视图及绑定新父视图的操作,_viewHotelRecommendCopy和_viewIntegralRecommendCopy在_rightView中重复addSubview道理同上,相当于只是改变了他们在父视图中的图层索引

    if (leftViewIndex == 0) {

        [_leftView addSubview: _viewHotelRecommend];

    }

    else{

        [_leftView addSubview: _viewIntegralRecommend];

    }

    if (centerViewIndex == 0) {

        [_centerView addSubview: _viewHotelRecommend];

    }

    else{

        [_centerView addSubview: _viewIntegralRecommend];

    }

    if (rightViewIndex == 0) {

        if (!_viewHotelRecommendCopy) {

            _viewHotelRecommendCopy = [self copyAView:_viewHotelRecommend];

            [_rightView addSubview:_viewHotelRecommendCopy];

        }

        else{

            [_rightView addSubview: _viewHotelRecommendCopy];

        }


    }

    else{

        [_rightView addSubview: _viewIntegralRecommendCopy];


    }


    self.scrollRecommend.contentOffset = CGPointMake(SCREEN_NEW_WIDTH, 0);


    if(!isTimeUp) {

        [moveTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:3.0]];

    }

    isTimeUp = NO;

}

//UIView归档/解档实现深拷贝

- (UIView*)copyAView:(UIView*)view

{

    NSData *tempArchive = [NSKeyedArchiver archivedDataWithRootObject:view];


    UIView *copyView = [NSKeyedUnarchiver unarchiveObjectWithData:tempArchive];


    // 在原View中遍历子控件

    for(UIView*subViewinview.subviews) {


        // 在复制好的View的子控件中遍历,找到与之对应的子控件

        for(UIView*copySubViewincopyView.subviews) {


            // 这里通过frame确定是否是同一个控件

            if ([NSStringFromCGRect(copySubView.frame) isEqualToString:NSStringFromCGRect(subView.frame)]) {

                //在xib中已经对需要处理的控件进行tag标记

                if(subView.tag==1) {

                    copySubView.layer.cornerRadius= subView.layer.cornerRadius;

                    copySubView.layer.masksToBounds=YES;

                }

                elseif(subView.tag==2){

                    UIButton*btn = (UIButton*)copySubView;

                    btn.titleLabel.font=font_Info;

                }

                elseif(subView.tag==3){

                    UILabel*lbl = (UILabel*)copySubView;

                    if(_sIntegralDesc.length>0) {

                        lbl.text= [NSStringstringWithFormat:@"您有%@积分可用",_sIntegralDesc];

                    }

                }

                elseif(subView.tag==4){

                    UILabel*lbl = (UILabel*)copySubView;

                    lbl.attributedText=_attHotelDesc;

                }

                elseif(subView.tag==5){

                    UILabel*lbl = (UILabel*)copySubView;

                    lbl.text=_sDestination;

                }

                break;

            }

        }

    }


    returncopyView;

}

- (void)scrollViewWillBeginDragging:(UIScrollView*)scrollView

{

    [moveTimer invalidate];

    moveTimer = nil;

}

- (void)scrollViewDidEndDragging:(UIScrollView*)scrollView willDecelerate:(BOOL)decelerate

{

    [self setUpTime];

}

你可能感兴趣的:(iOS 简单易学的无线滚动,支持UIImageView、UIView)