您的位置:首页 > 移动开发 > IOS开发

ios无线轮播图

2015-06-25 13:05 435 查看
思路:在ScrollView的contentSiz设置成ScrollView宽的度的三倍。创建三个循环的View。当滑动的时候,正常滑动活动结束。滑动结束设置contentOffset将视图滑动到中间去。将后面的数据赋值到中间。。。简单说就是视图只显示中间一张视,交换数据实现不同数据的显示。。

#import <UIKit/UIKit.h>

@protocol YQImageLoopDelegate <NSObject>

- (void)YQImageLoopConfigDataArray:(NSArray *)yq_dataArray loopView:(UIView *)yq_loopView index:(NSInteger)index;
@optional
- (void)YQImageLoopClickImageOfindex:(NSInteger)index dataArray:(NSArray *)yq_dataArray;

@end

@interface YQImageLoop : UIView

- (instancetype)initWithFrame:(CGRect)frame loopView:(UIView *)loopView loopDelagate:(id<YQImageLoopDelegate>)delegate;// 初始化
@property (nonatomic, strong) UIScrollView *yq_scrollView;
@property (nonatomic, strong) UIPageControl *yq_pageControl;
@property (nonatomic, assign) NSTimeInterval yq_timerLoopTime;     // timer循环时间
@property (nonatomic, assign) NSTimeInterval yq_animactionTime;    // 动画时间
@property (nonatomic, strong) NSArray *yq_dataArray;        // 循环的数据
@property (nonatomic, assign) BOOL yq_isLoop;                      // 是否循环
@property (nonatomic, assign) id<YQImageLoopDelegate>delegate;     // 代理

#pragma mark 事件-timer事件
-(void)addTimer:(NSTimeInterval)timeInterval;
- (void)cancelTimerLoop;
@end
#import "YQImageLoop.h"

typedef NS_ENUM(NSInteger, YQScrollDirection)
{
YQRight,
YQLeft,
};

@interface YQImageLoop ()<UIScrollViewDelegate>
@property (nonatomic, strong) NSTimer *yq_timer;            // 循环timer定时器
@property (nonatomic, strong) UIView *yq_loopView;          // 循环的视图
@property (nonatomic, strong) NSMutableArray *yq_recordLoopViewArray; // 存储循环视图
@property (nonatomic, assign) BOOL isDragg;    // 是否拖拽
@property (nonatomic, assign) BOOL isGetData;  // 是否活的轮播的数据

@property (nonatomic, strong) UITapGestureRecognizer *tapGR;

@end

@implementation YQImageLoop

- (instancetype)initWithFrame:(CGRect)frame loopView:(UIView *)loopView loopDelagate:(id<YQImageLoopDelegate>)delegate
{
self = [super initWithFrame:frame];
if (self) {
_delegate = delegate;
_yq_loopView = loopView;
[self addDatas];
[self addViews];
}
return self;
}

#pragma mark 初始
- (void)addViews
{
self.yq_scrollView.frame = self.frame;
[self addSubview:self.yq_scrollView];
[self addSubview:self.yq_pageControl];

self.tapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGRAction:)];
[self addGestureRecognizer:_tapGR];
}
- (void)addDatas
{
_isGetData = NO;
_isDragg = NO;
_yq_dataArray = [[NSMutableArray alloc] initWithCapacity:30];
[self addObserver:self forKeyPath:@"yq_dataArray" options:NSKeyValueObservingOptionNew context:nil];
}
#pragma mark 初始-事件
#pragma mark 初始-事件-添加循环视图
- (void)configScrollViewLoopView
{
for (int i=0; i<3; i++) {
UIView *newLoopView = [self duplicate:self.yq_loopView];
newLoopView.frame = CGRectMake(self.frame.size.width*i, 0, self.frame.size.width, self.frame.size.height);
[self.yq_recordLoopViewArray addObject:newLoopView];
[_yq_scrollView addSubview:newLoopView];
}
}
// 复制一份view
- (UIView*)duplicate:(UIView*)view1
{
NSData * tempArchive = [NSKeyedArchiver archivedDataWithRootObject:view1];
return [NSKeyedUnarchiver unarchiveObjectWithData:tempArchive];
}

- (void)setYq_timerLoopTime:(NSTimeInterval)yq_timerLoopTime
{
_yq_timerLoopTime = yq_timerLoopTime;
[self addTimer:_yq_timerLoopTime];
}

#pragma mark 代理-delegate
#pragma mark 代理-scrollViewDelegate

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
// 拖拽开始
self.isDragg = YES;
[self cancelTimerLoop];

}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
// 拖拽完成
if (self.isDragg == YES) {
[self addTimer:self.yq_timerLoopTime];
self.isDragg = NO;
}
// changDataOrPage
[self YQScrollViewDidEndDecelerating:_yq_scrollView.contentOffset.x isGetData:_isGetData];
}

#pragma mark 事件
#pragma mark 事件-timer事件
-(void)addTimer:(NSTimeInterval)timeInterval
{
if (self.yq_timer == nil) {
self.yq_timer = [NSTimer scheduledTimerWithTimeInterval:timeInterval target:self selector:@selector(timeLoopAction:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:_yq_timer forMode:NSRunLoopCommonModes];
}
}
- (void)cancelTimerLoop
{
[self.yq_timer invalidate];
self.yq_timer = nil;
}
- (void)timeLoopAction:(NSTimer *)sender
{
[UIView animateWithDuration:self.yq_animactionTime animations:^{
self.yq_scrollView.contentOffset = CGPointMake(self.frame.size.width*2, 0);
} completion:^(BOOL finished) {
self.yq_scrollView.contentOffset = CGPointMake(self.frame.size.width, 0);
if (_isGetData == YES) {
[self changeDataAndPage:YQLeft];
}else{
[self changePage:YQLeft];
}
}];
}

#pragma mark 事件-滑动完成改变数据、
- (void)YQScrollViewDidEndDecelerating:(CGFloat)contentOffsetX isGetData:(BOOL)getData
{
if (contentOffsetX == 0) {
if (getData == YES){
[self changeDataAndPage:YQRight];
}else{
[self changePage:YQRight];
}
_yq_scrollView.contentOffset = CGPointMake(self.frame.size.width, 0);
}else if(contentOffsetX == self.frame.size.width*2){
if (getData == YES) {
[self changeDataAndPage:YQLeft];
}else{
[self changePage:YQLeft];
}
_yq_scrollView.contentOffset = CGPointMake(self.frame.size.width, 0);
}
}

// data and page
- (void)changeDataAndPage:(YQScrollDirection)scrollDirection
{
[self changePage:scrollDirection];
[self changeData];
}
// page
- (void)changePage:(YQScrollDirection)scrollDirection
{
if (scrollDirection == YQRight) {
// pageCotrol 变化
if (_yq_pageControl.currentPage == 0){
_yq_pageControl.currentPage = _yq_pageControl.numberOfPages-1;
}else{
_yq_pageControl.currentPage -= 1;
}
}else if(scrollDirection == YQLeft){
if(_yq_pageControl.currentPage == _yq_pageControl.numberOfPages-1){
_yq_pageControl.currentPage = 0;
}else{
_yq_pageControl.currentPage += 1;
}
}
}
// data
- (void)changeData
{
if (_yq_pageControl.currentPage == 0){
if (_delegate && [_delegate respondsToSelector:@selector(YQImageLoopConfigDataArray:loopView:index:)]) {
[_delegate YQImageLoopConfigDataArray:_yq_dataArray loopView:_yq_recordLoopViewArray[0] index:_yq_pageControl.numberOfPages-1];
[_delegate YQImageLoopConfigDataArray:_yq_dataArray loopView:_yq_recordLoopViewArray[1] index:0];
[_delegate YQImageLoopConfigDataArray:_yq_dataArray loopView:_yq_recordLoopViewArray[2] index:1];
}
}else if(_yq_pageControl.currentPage == _yq_pageControl.numberOfPages-1){
if (_delegate && [_delegate respondsToSelector:@selector(YQImageLoopConfigDataArray:loopView:index:)]) {
[_delegate YQImageLoopConfigDataArray:_yq_dataArray loopView:_yq_recordLoopViewArray[0] index:_yq_pageControl.currentPage-1];
[_delegate YQImageLoopConfigDataArray:_yq_dataArray loopView:_yq_recordLoopViewArray[1] index:_yq_pageControl.currentPage];
[_delegate YQImageLoopConfigDataArray:_yq_dataArray loopView:_yq_recordLoopViewArray[2] index:0];
}
}else{
if (_delegate && [_delegate respondsToSelector:@selector(YQImageLoopConfigDataArray:loopView:index:)]) {
[_delegate YQImageLoopConfigDataArray:_yq_dataArray loopView:_yq_recordLoopViewArray[0] index:_yq_pageControl.currentPage-1];
[_delegate YQImageLoopConfigDataArray:_yq_dataArray loopView:_yq_recordLoopViewArray[1] index:_yq_pageControl.currentPage];
[_de
9d4e
legate YQImageLoopConfigDataArray:_yq_dataArray loopView:_yq_recordLoopViewArray[2] index:_yq_pageControl.currentPage+1];
}
}
}

#pragma mark 监听
#pragma mark 监听-属性
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"yq_dataArray"]) {
if (change[@"new"] != nil && ([change[@"new"] isKindOfClass:[NSArray class]] && ([(NSArray *)change[@"new"] count] != 0) && ([change[@"new"] isKindOfClass:[NSDictionary class]]|| [(NSDictionary *)change[@"new"] count] != 0))){
_isGetData = YES;
[self observeValueFinish];
}
}
}
#pragma mark 监听-事件
- (void)observeValueFinish
{
self.yq_pageControl.numberOfPages = self.yq_dataArray.count;
if (_delegate && [_delegate respondsToSelector:@selector(YQImageLoopConfigDataArray:loopView:index:)]) {
[_delegate YQImageLoopConfigDataArray:_yq_dataArray loopView:_yq_recordLoopViewArray[0] index:_yq_dataArray.count-1];
[_delegate YQImageLoopConfigDataArray:_yq_dataArray loopView:_yq_recordLoopViewArray[1] index:0];
[_delegate YQImageLoopConfigDataArray:_yq_dataArray loopView:_yq_recordLoopViewArray[2] index:1];
}
}

#pragma mark 点击事件
- (void)tapGRAction:(UITapGestureRecognizer *)sender
{
if (_delegate && [_delegate respondsToSelector:@selector(YQImageLoopClickImageOfindex:dataArray:)]) {
[_delegate YQImageLoopClickImageOfindex:self.yq_pageControl.currentPage dataArray:_yq_dataArray];
}
}

#pragma mark setter and getter
- (UIPageControl *)yq_pageControl
{
if (_yq_pageControl == nil) {
_yq_pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(0, self.frame.size.height-30, self.frame.size.width, 30)];
_yq_pageControl.numberOfPages = 4;
}
return _yq_pageControl;
}
- (UIScrollView *)yq_scrollView
{
if (_yq_scrollView == nil){
_yq_scrollView = [[UIScrollView alloc] initWithFrame:self.frame];
_yq_scrollView.delegate = self;
_yq_scrollView.contentSize = CGSizeMake(CGRectGetWidth(self.frame)*3, CGRectGetHeight(self.frame));
_yq_scrollView.contentOffset = CGPointMake(CGRectGetWidth(self.frame), 0);
_yq_scrollView.pagingEnabled = YES;
_yq_scrollView.bounces = NO;
_yq_scrollView.showsHorizontalScrollIndicator = NO;
_yq_scrollView.showsVerticalScrollIndicator = NO;
[self configScrollViewLoopView];
}
return _yq_scrollView;
}

- (NSMutableArray *)yq_recordLoopViewArray
{
if (_yq_recordLoopViewArray == nil) {
_yq_recordLoopViewArray = [[NSMutableArray alloc] initWithCapacity:30];
}
return _yq_recordLoopViewArray;
}

- (void)dealloc
{
[self removeObserver:self forKeyPath:@"yq_dataArray" context:nil];
}


注意事项:NSTimer 加到当前的runloop中,才能真正的实现循环。。。大家不良了解runloop的可以自行百度去吧。在下就不在这班门弄斧,讲一些与主题无关的了。。。
// 图片资源
self.imageAddressArray = [[NSArray alloc] initWithObjects:@"http://img1.3lian.com/2015/w1/47/d/1.jpg",@"http://img1.3lian.com/2015/w1/47/d/9.jpg",@"http://img1.3lian.com/2015/w1/47/d/8.jpg",@"http://img1.3lian.com/2015/w2/10/d/46.jpg",@"http://img1.3lian.com/2015/w1/47/d/7.jpg",@"http://img1.3lian.com/2015/w1/47/d/6.jpg", nil];

// 自定义循环视图
UIImageView *image = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"zw.png"]];
//_________________________________________________________
_yqImageLoop = [[YQImageLoop alloc] initWithFrame:self.view.frame loopView:image loopDelagate:self];
_yqImageLoop.yq_pageControl.currentPageIndicatorTintColor = [UIColor redColor];
_yqImageLoop.yq_timerLoopTime = 3.0f;
_yqImageLoop.yq_animactionTime = 1.5f;
[self.view addSubview:_yqImageLoop];

// 延迟赋数据,模仿网络请求
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
_yqImageLoop.yq_dataArray = _imageAddressArray;
});

看一下如何使用吧
// 轮播图赋值数据
- (void)YQImageLoopConfigDataArray:(NSArray *)yq_dataArray loopView:(UIView *)yq_loopView index:(NSInteger)index
{
[((UIImageView *)yq_loopView) sd_setImageWithURL:[NSURL URLWithString:yq_dataArray[index]] placeholderImage:[UIImage imageNamed:@"zw.png"]];
}

// 点击轮播
- (void)YQImageLoopClickImageOfindex:(NSInteger)index dataArray:(NSArray *)yq_dataArray
{
NSLog(@"%@",yq_dataArray[index]);
}

/*
在视图将要出现的时候加上事件循环, 消失的时候取消事件循环
*/
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[_yqImageLoop addTimer:3.0f]; // 添加时间循环
}

- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[_yqImageLoop cancelTimerLoop]; // 取消事件循环
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息