iOS 轮播图

今天给大家带来的是轮播图的实现(包括纵向轮播图,以及自定义 UIPageController),这里简单的讲述下轮播图的原理假如说,我现在有3张图片,正常是这样摆放的


那么我要想实现轮播的效果就需要在1前加个3,在3后面加个1顺序就是3`- 1 - 2 - 3 - 1`,这样的话当用户向左滑动时候当现实1`的时候,改变 scrollView 的 contentOffSet, 让他显示1,同理向右滑动的时候,当显示3`的时候改变 scrollView 的 contentOffSet, 让他显示3,(由于没有效果图,大家只能自行脑补一下了...... sorry,以后会补上的),

只要想明白了其中的逻辑,实现起来就比较方便了,下面是代码,还是只要将这两个文件之间导入到工程即可(这里要说明一下,由于为了使用的方便,这次封装的比较"狠",大家只要掉一行代码就可以实现,但是在使用的时候,请确保工程中已经导入了SDWebImage,因为在赋值图片的时候使用了它的方法,不导入的话是会报错滴..)

首先,自定义一个继承于UIView的类,(cycleScrollView)
//
//  cycleScrollView.h
//  cycleScrollView
//
//  Created by Amydom on 16/12/16.
//  Copyright © 2016年 Amydom. All rights reserved.
//

#import <UIKit/UIKit.h>

//imageView 的点击代理
@protocol cycleScrollViewDelegate <NSObject>

- (void)TouchImageViewToPush : (NSInteger) tag;

@end

@interface cycleScrollView : UIView

//创建轮播图
- (void)attributeForcycleScrollViewWithArray : (NSMutableArray *)dataArr
                          isCycleOrientation : (NSInteger)i;

//是否打开定时器
- (void)WhetherOpenTimer : (BOOL)isOpened;

@property (nonatomic , assign) id <cycleScrollViewDelegate>cycleDelegete;


@end

//
//  cycleScrollView.m
//  cycleScrollView
//
//  Created by Amydom on 16/12/16.
//  Copyright © 2016年 Amydom. All rights reserved.
//

#import "cycleScrollView.h"
#import "UIImageView+WebCache.h"
#import "cycleScrollModel.h"

#define Screen_W [UIScreen mainScreen].bounds.size.width


#pragma Mark - 判断轮播方向
typedef NS_ENUM(NSInteger, isCycle) {
    //以下是枚举成员
    HorizontalCycleScroll = 1,//横向
    VerticalCycleScroll = 2,//纵向
    
};

@interface cycleScrollView()<UIScrollViewDelegate>{
    
    UIScrollView *_scrollView;
    UIPageControl *pageC;
    NSMutableArray *_RotateArr;
    UIView *_viewPage;
    NSTimer *_time;
    NSInteger Orientation;
    BOOL _isOpen;
    
    
}

@end

@implementation cycleScrollView


- (instancetype)initWithFrame:(CGRect)frame{
    
    if (self = [super initWithFrame:frame]) {
        _scrollView = [[UIScrollView alloc]initWithFrame:frame];
        [self addSubview:_scrollView];
        [self attributeForScroll];
        _isOpen = NO;
    }

    return self;
    
}


//轮播图创建
- (void)attributeForcycleScrollViewWithArray : (NSMutableArray *)dataArr isCycleOrientation : (NSInteger)i{
    
    Orientation = i;
    NSMutableArray *image_urlArr = [NSMutableArray array];
    _RotateArr = [NSMutableArray arrayWithArray:dataArr];
    //对数据进行遍历,来获取 url
    if (_RotateArr.count != 0) {
        
        for (int i = 0; i < _RotateArr.count; i++) {
            
            cycleScrollModel *cycleModel = [_RotateArr objectAtIndex:i];
            NSURL *url = [NSURL URLWithString:cycleModel.image_url];
            [image_urlArr addObject:url];
            
        }
    }

        NSURL *firstImageUrl = [image_urlArr lastObject];
        NSURL *lastImageUrl = [image_urlArr objectAtIndex:0];
        //insertObject插入
        //UIMutableArray 执行 insertObject 操作时, 数组的长度会改变的,他会根据你指定的 index 去指定的位置将该元素插入数组,但是插入的同时, index 后面的所有元素都要往后排, 就跟排队有人插队是一个道理
        [image_urlArr insertObject:firstImageUrl atIndex:0];
        [image_urlArr addObject:lastImageUrl];
    //判断方向
    if (i == HorizontalCycleScroll) {
        [_viewPage removeFromSuperview];//测试用
        _scrollView.contentSize = CGSizeMake(Screen_W * (image_urlArr.count + 2), 0);
    
        for (int i = 0; i < image_urlArr.count; i++) {
            
            UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(Screen_W * i, 0, Screen_W, self.frame.size.height)];
            imageView.userInteractionEnabled = YES;
            [_scrollView addSubview:imageView];
            UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(TapAction:)];
            [imageView addGestureRecognizer:tap];
            imageView.tag = 1000 + i;
            [imageView sd_setImageWithURL:[image_urlArr objectAtIndex:i] placeholderImage:[UIImage imageNamed:@""]];

        }
#pragma mark - 页码
            pageC = [[UIPageControl alloc]initWithFrame:CGRectMake(Screen_W - 100, self.frame.size.height - 30, Screen_W / 7, 30)];
//         pageC = [[UIPageControl alloc]initWithFrame:CGRectMake(Screen_W - 50, self.frame.size.height - 70, 30, self.frame.size.height / 7)];
            pageC.backgroundColor = [UIColor clearColor];
            [self addSubview:pageC];
            //设置页码个数
            pageC.numberOfPages = _RotateArr.count;
            //点的颜色
            pageC.currentPageIndicatorTintColor = [UIColor whiteColor];
            pageC.pageIndicatorTintColor = [UIColor lightGrayColor];
            //初始位置
            pageC.currentPage = 0;
            [pageC addTarget:self action:@selector(pageAction:) forControlEvents:UIControlEventValueChanged];
        
    }
    
    if (i == VerticalCycleScroll){
        
        [pageC removeFromSuperview];//测试用
        _scrollView.contentSize = CGSizeMake(0, self.frame.size.height * (image_urlArr.count + 2));
        
        for (int i = 0; i < image_urlArr.count; i++) {
            
            UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, self.frame.size.height * i, Screen_W, self.frame.size.height)];
            imageView.userInteractionEnabled = YES;
            [_scrollView addSubview:imageView];
            UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(TapAction:)];
            [imageView addGestureRecognizer:tap];
            imageView.tag = 1000 + i;
            [imageView sd_setImageWithURL:[image_urlArr objectAtIndex:i] placeholderImage:[UIImage imageNamed:@""]];
            
        }
        //自定义 pageController
         [self customButton:_RotateArr.count];
    }
}

- (void)WhetherOpenTimer : (BOOL)isOpened{
    
    _isOpen = isOpened;
    if (_isOpen) {
        
        [self timerBegin];
        
    }else{
        
        [self timerClose];
        
    }
    

}

//******************************私有方法***************************************
#pragma mark - 代理
- (void)TapAction:(UITapGestureRecognizer *)tap{
    
    [self.cycleDelegete TouchImageViewToPush:tap.view.tag - 1000 - 1];
    
}
#pragma mark -- 页码切换
-(void)pageAction:(UIPageControl *)page{
    
    [_scrollView setContentOffset:CGPointMake(Screen_W * (page.currentPage + 1), 0) animated:YES];
}

#pragma mark -- 图片无限循环(减速停止时触发)
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    
    if (Orientation == HorizontalCycleScroll) {
        
        if (_scrollView.contentOffset.x == 0) {
            
            _scrollView.contentOffset = CGPointMake(Screen_W * _RotateArr.count, 0);
            
        }else if (_scrollView.contentOffset.x == Screen_W * (_RotateArr.count + 1)){
            
            _scrollView.contentOffset = CGPointMake(Screen_W, 0);
            
        }
        pageC.currentPage = _scrollView.contentOffset.x / Screen_W - 1;

    }
    
    if (Orientation == VerticalCycleScroll){
        
        if (_scrollView.contentOffset.y == 0){
            
             _scrollView.contentOffset = CGPointMake(0, self.frame.size.height * _RotateArr.count);
            
        }else if (_scrollView.contentOffset.y == self.frame.size.height * (_RotateArr.count + 1)){
            
            _scrollView.contentOffset = CGPointMake(0, self.frame.size.height);
            
        }
        
        NSInteger tag = _scrollView.contentOffset.y / self.frame.size.height ;
        //获取 view 上 tag 为3000的控件
        UILabel *label = (UILabel *)[_viewPage viewWithTag:3000];
        if (tag == 6) {//最后一张时,初始化位置
            tag = 0;
            label.frame = CGRectMake(0, 0, 6, 6);
        }else{
            label.frame = CGRectMake(0, tag * 15, 6, 6);
            
        }
       
    }
    
    
}
#pragma mark - 定时器开始
- (void)timerBegin{
    if (!_time) {
        
        _time = [NSTimer timerWithTimeInterval:3 target:self selector:@selector(changeAction:) userInfo:@"time" repeats:YES];
        [[NSRunLoop currentRunLoop] addTimer:_time forMode:NSRunLoopCommonModes];

    }
  
}

- (void)timerClose{
    
    [_time invalidate];
    _time = nil;
}
#pragma mark -- 定时器触发
- (void)changeAction:(NSTimer *)time{
    
    if (Orientation == HorizontalCycleScroll) {
        
        [UIView animateWithDuration:0.5 animations:^{
            
            [_scrollView setContentOffset:CGPointMake(_scrollView.contentOffset.x + Screen_W, 0) animated:YES];
            pageC.currentPage = _scrollView.contentOffset.x / Screen_W;
            
        }];
        //循环(包括page)
        //可以理解为到最后一张图就全部初始化
        if (_scrollView.contentOffset.x == _RotateArr.count * Screen_W) {
            //相当于初始化
            _scrollView.contentOffset = CGPointMake(0, 0);
            
            
        }
        pageC.currentPage = _scrollView.contentOffset.x / Screen_W;
    }
    
    
    
    if (Orientation == VerticalCycleScroll) {
        
        [UIView animateWithDuration:0.5 animations:^{
            
            [_scrollView setContentOffset:CGPointMake(0 , _scrollView.contentOffset.y + self.frame.size.height) animated:YES];
            
        }];
        //循环(包括page)
        //可以理解为到最后一张图就全部初始化
        if (_scrollView.contentOffset.y == _RotateArr.count * self.frame.size.height) {
            //相当于初始化
            _scrollView.contentOffset = CGPointMake(0, 0);
            
            
        }
        NSInteger tag = _scrollView.contentOffset.y / self.frame.size.height + 1;
        //获取 view 上 tag 为3000的控件
        UILabel *label = (UILabel *)[_viewPage viewWithTag:3000];
        if (tag == 6) {//最后一张时,初始化位置
            tag = 0;
            label.frame = CGRectMake(0, 0, 6, 6);
        }else{
            label.frame = CGRectMake(0, tag * 15, 6, 6);
            
        }
      
    }
    
}

#pragma mark -- 手指触碰时停止定时器
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    [self timerClose];
    
}
#pragma mark -- 手指离开继续滑动
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    if (_isOpen) {
        
        [self timerBegin];

    }

}


- (void)attributeForScroll{
    
    _scrollView.delegate = self;
    
    _scrollView.pagingEnabled = YES;
    //用户交互
    _scrollView.userInteractionEnabled = YES;
    //取消边界反弹效果
    _scrollView.bounces = NO;
    //设置滑动条
    _scrollView.showsHorizontalScrollIndicator = NO;
    _scrollView.showsVerticalScrollIndicator = NO;
    //初始偏移量为第二张图片
    _scrollView.contentOffset = CGPointMake(Screen_W, 0);
    
}

#pragma mark - 自定义 pageController
- (void)customButton:(NSInteger)btnCount {
    
    _viewPage = [[UIView alloc]initWithFrame:CGRectMake(Screen_W - 15, 60, 20, 100)];
    [self addSubview:_viewPage];
    
    for ( NSInteger i = 0; i < btnCount; i++) {
        UIButton *button= [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake(0, i*15, 6, 6);
        button.clipsToBounds = YES;
        button.layer.cornerRadius = 3;
        button.tag = 1001+i;
        button.backgroundColor = [UIColor grayColor];
        
        [_viewPage addSubview:button];

    }
    
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 6, 6)];
    label.backgroundColor = [UIColor whiteColor];
    label.clipsToBounds = YES;
    label.tag = 3000;
    label.layer.cornerRadius = 3;
    [_viewPage addSubview:label];

}


@end


好了,主要的工程已经完成了,下面就是使用了,之前说了,由于封装的比较"狠",所以在外面用起来就比较简单,给大家看下


这是我关于轮播图的网络请求,我用到的就是这个圈上的数组,也就是拿到数据后的数组


之后之间调用下方法,传进刚才的数组,一切就都 OK 了..


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值