ios Objective-c 自己動手封裝輪播圖

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

        }

    }];

}



以上就是輪播圖的簡單製作了,封裝好的輪播圖->

輪播圖.zip

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章