具體使用: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)];
}
}
}];
}