ios 自己动手封装轮播图

具体使用: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

发布了38 篇原创文章 · 获赞 34 · 访问量 8794

猜你喜欢

转载自blog.csdn.net/qq_41586150/article/details/104402211