美文网首页
iOS 简单易学的无线滚动,支持UIImageView、UIVi

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

作者: 瞎编程 | 来源:发表于2018-05-14 13:37 被阅读11次

    思路: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、UIVi

          本文链接:https://www.haomeiwen.com/subject/npyddftx.html