具体使用:XMRotationChartView
极简版实现
XMQueue.h->XMQueue
1.定义接口XMRotationChartView并实现
#import <UIKit/UIKit.h>
@interface XMRotationChartView : UIView
@end
#import "XMRotationChartView.h"
#import "XMQueue.h"
@interface XMRotationChartView()
@end
@implementation XMRotationChartView
@end
2.添加属性contentView,重写初始化方法,在初始化的时候添加XMRotationChartView上到用以显示轮播图
@interface XMRotationChartView()
///轮播图视图
@property (nonatomic,strong) UIView *contentView;
@end
@implementation XMRotationChartView
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
///初始化轮播图视图
_contentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
///超出部分裁剪
_contentView.clipsToBounds = YES;
///添加到XMRotationChartView
[self addSubview:_contentView];
}
return self;
}
3.自定义代理,给XMRotationChartView添加代理属性
需要先声明XMRotationChartViewDelegate,
因为XMRotationChartViewDelegate定义是在XMRotationChartView代码下边.
不然会编译不通过
///声明XMRotationChartViewDelegate
@protocol XMRotationChartViewDelegate;
@interface XMRotationChartView : UIView
///添加delegate给外界,使用轮播图的类可以代理它
@property (nonatomic, assign) id <XMRotationChartViewDelegate> delegate;
@end
///定义XMRotationChartViewDelegate
@protocol XMRotationChartViewDelegate <NSObject>
@required
///轮播图数量
- (NSInteger)rotationChartCount:(XMRotationChartView *)RotationChart;
///初始化轮播图片
- (UIImageView *)rotationChartAtIndex:(XMRotationChartView *)RotationChart atIndex:(NSInteger)index;
@end
4.监听代理,如果delegate不为nil,自然是外界进行了赋值…
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
///初始化轮播图视图
_contentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
///超出部分裁剪
_contentView.clipsToBounds = YES;
///添加到XMRotationChartView
[self addSubview:_contentView];
///监听代理
[self addObserver:self forKeyPath:@"delegate" options:NSKeyValueObservingOptionNew context:nil];
}
return self;
}
/// 代理方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
///delegate值改变
if ([@"delegate"isEqualToString:keyPath]) {
///假如delegate不为nil
if (_delegate != nil) {
///获得轮播总数
NSInteger rotationChartCount = [_delegate rotationChartCount:self];
/// 通过总数去遍历执行代理方法获取外界传的imageView添加到轮播图
for (int i = 0; i < rotationChartCount; i++) {
///获得imageView
UIImageView *imageView = [_delegate rotationChartAtIndex:self atIndex:i];
///设置它的宽高和位置
[imageView setFrame:CGRectMake(- self.contentView.frame.size.width + i * self.contentView.frame.size.width , 0 ,
self.contentView.frame.size.width, self.contentView.frame.size.height)];
[_contentView addSubview:imageView];
}
///_contentView图片位置 0 1 0 0 0 0 0 ...
///1那张图片显示在屏幕上,(留个空位是为了自动轮播)
}
}
}
5.添加属性imageViewList,imageViewXQueue保存imageView对象和x坐标
@interface XMRotationChartView()
///轮播图视图
@property (nonatomic,strong) UIView *contentView;
///轮播图片集合
@property (nonatomic,strong) NSMutableArray<UIImageView *> *imageViewList;
///轮播图片x坐标队列
@property (nonatomic,strong) XMQueue *imageViewXQueue;
@end
/// 代理方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
///delegate值改变
if ([@"delegate"isEqualToString:keyPath]) {
///假如delegate不为nil
if (_delegate != nil) {
///获得轮播总数
NSInteger rotationChartCount = [_delegate rotationChartCount:self];
///初始化轮播图数组
_imageViewList = [[NSMutableArray alloc] initWithCapacity:rotationChartCount];
///初始化轮播图x坐标队列
_imageViewXQueue = [[XMQueue alloc] init];
for (int i = 0; i < rotationChartCount; i++) {
UIImageView *imageView = [_delegate rotationChartAtIndex:self atIndex:i];
[imageView setFrame:CGRectMake(- self.contentView.frame.size.width + i * self.contentView.frame.size.width , 0 ,
self.contentView.frame.size.width, self.contentView.frame.size.height)];
///添加到轮播图数组
[_imageViewList addObject:imageView];
///添加x坐标到轮播图x坐标队列
[_imageViewXQueue add:[NSNumber numberWithFloat:imageView.frame.origin.x]];
[_contentView addSubview:imageView];
}
}
}
6.添加计时器属性,开启计时器,给计时器添加轮播方法
@interface XMRotationChartView()
///轮播图视图
@property (nonatomic,strong) UIView *contentView;
///轮播图片集合
@property (nonatomic,strong) NSMutableArray<UIImageView *> *imageViewList;
///轮播图片x坐标队列
@property (nonatomic,strong) XMQueue *imageViewXQueue;
///轮播计时器
@property (nonatomic,strong) NSTimer *timer;
@end
/// 代理方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
///delegate值改变
if ([@"delegate"isEqualToString:keyPath]) {
///假如delegate不为nil
if (_delegate != nil) {
NSInteger rotationChartCount = [_delegate rotationChartCount:self];
_imageViewList = [[NSMutableArray alloc] initWithCapacity:rotationChartCount];
_imageViewXQueue = [[XMQueue alloc] init];
for (int i = 0; i < rotationChartCount; i++) {
UIImageView *imageView = [_delegate rotationChartAtIndex:self atIndex:i];
[imageView setFrame:CGRectMake(- self.contentView.frame.size.width + i * self.contentView.frame.size.width , 0 ,
self.contentView.frame.size.width, self.contentView.frame.size.height)];
[_imageViewList addObject:imageView];
[_imageViewXQueue add:[NSNumber numberWithFloat:imageView.frame.origin.x]];
[_contentView addSubview:imageView];
///计时器添加方法
_timer = [NSTimer scheduledTimerWithTimeInterval:3.0 target:self selector:@selector(rightRotationChart) userInfo:nil repeats:YES];
///开启计时器
[_timer fire];
}
}
}
///轮播方法
- (void) rightRotationChart{
}
7.轮播方法实现
///轮播方法
- (void) rightRotationChart{
///把队列内第一个x坐标添加到队列尾部(这样模拟了轮播图的轮播)
[_imageViewXQueue add:[_imageViewXQueue next]];
///把当前队列转换成数组个数
NSArray *newImageXArray = [_imageViewXQueue arrayCopy];
///动画方法
[UIView animateWithDuration:_speed animations:^{
///遍历所有imageView
for (int i = 0; i < [self->_delegate rotationChartCount:self]; i++) {
UIImageView *image = [self->_imageViewList objectAtIndex:i];
///给imageView通过x队列赋值x(因为在动画块中,所以就会有轮播的动画)
[image setFrame:CGRectMake([(NSNumber *)[newImageXArray objectAtIndex:i] floatValue], image.frame.origin.y, image.frame.size.width, image.frame.size.height)];
}
}];
}
8.去掉队尾的imageView到队首的动画
///轮播方法
- (void) rightRotationChart{
///把队列内第一个x坐标添加到队列尾部(这样模拟了轮播图的轮播)
[_imageViewXQueue add:[_imageViewXQueue next]];
///把当前队列转换成数组个数
NSArray *newImageXArray = [_imageViewXQueue arrayCopy];
///动画方法
[UIView animateWithDuration:_speed animations:^{
///遍历所有imageView
for (int i = 0; i < [self->_delegate rotationChartCount:self]; i++) {
UIImageView *image = [self->_imageViewList objectAtIndex:i];
///假如这个imageView的x已经是在最后了
if (image.frame.origin.x == ([self->_delegate rotationChartCount:self] - 2) * image.frame.size.width) {
///回到主线程,执行修改x坐标的操作,不触发动画
dispatch_async(dispatch_get_main_queue(), ^{
[image setFrame:CGRectMake([(NSNumber *)[newImageXArray objectAtIndex:i] floatValue], image.frame.origin.y, image.frame.size.width, image.frame.size.height)];
});
}else{
[image setFrame:CGRectMake([(NSNumber *)[newImageXArray objectAtIndex:i] floatValue], image.frame.origin.y, image.frame.size.width, image.frame.size.height)];
}
}
}];
}