图片无限轮播

新增样式

 

#import <UIKit/UIKit.h>

/** 方向*/

typedef NS_ENUM(NSInteger, ZJImageLoopViewScrollDirection ) {

    /** 不 自 动 循 环(即不开启定时器)*/

    ZJImageLoopViewScrollDirectionNone        = 0,

    /** 从 右 往 左 自 动 循 环*/

    ZJImageLoopViewScrollDirectionRightToLeft = 1,

    /** 从 左 往 右 自 动 循 环*/

    ZJImageLoopViewScrollDirectionLeftToRight = 2,

};

/** 样式*/

typedef NS_ENUM(NSInteger, ZJImageLoopViewScrollStyle ) {

    /** 默认 平滑*/

    ZJImageLoopViewScrollStyleNone = 0,

    /** 前后缩放*/

    ZJImageLoopViewScrollStyleZoom = 1,

    /** 两端缩放*/

    ZJImageLoopViewScrollStyleJustifyZoom = 2,

};

 

@class ZJImageLoopView;

@protocol ZJImageLoopViewDelegate <NSObject>

@optional

/** 点击时当前显示*/

-(void)ZJImageLoopView:(ZJImageLoopView*)view didSelectSubviewAtIndex:(NSInteger)index;

/** 停止时当前显示*/

-(void)ZJImageLoopView:(ZJImageLoopView*)view didEndDeceleratingAtIndex:(NSInteger)index;

@end

NS_ASSUME_NONNULL_BEGIN

 

@interface ZJImageLoopView : UIView

@property(nonatomic,assign) ZJImageLoopViewScrollDirection scrollDirection;

@property(nonatomic,weak) id <ZJImageLoopViewDelegate> delegate;

 

- (instancetype)initWithFrame:(CGRect)frame style:(ZJImageLoopViewScrollStyle)style;

 

- (void)showImagesWithImageStrs:(NSArray<NSString*>*)imageStrs;

- (void)showDefaultCurrentIndex:(NSInteger)currentIndex;

 

/** 回调方法*/

- (void)didSelectSubviewAtIndex:(void(^)(NSInteger index))block;

- (void)didEndDeceleratingAtIndex:(void(^)(NSInteger index))block;

@end

 

NS_ASSUME_NONNULL_END

 

 

//

//  ZJImageLoopView.m

//  ZJUMManager

//

//  Created by lizhijiang on 2019/10/28.

//  Copyright © 2019年 lizhijiang. All rights reserved.

//

 

#import "ZJImageLoopView.h"

@interface ZJImageLoopView ()<UIScrollViewDelegate>

@property(nonatomic,strong) NSArray <NSString*>* dataArray;

@property(nonatomic,assign) NSInteger currentIndex;

@property(nonatomic,strong) dispatch_source_t timer;;

@property(nonatomic,weak) UIScrollView * scrollview;

@property(nonatomic,weak) UIImageView  * leftImgView;

@property(nonatomic,weak) UIImageView  * centerImgView;

@property(nonatomic,weak) UIImageView  * rightImgView;

 

@property(nonatomic,assign) CGRect originalleftFrame;

@property(nonatomic,assign) CGRect originalcentertFrame;

@property(nonatomic,assign) CGRect originalrightFrame;

 

@property(nonatomic,assign) ZJImageLoopViewScrollStyle style;

@property(nonatomic,copy) void(^didSelectSubviewAtIndexBlock)(NSInteger index);

@property(nonatomic,copy) void(^didEndDeceleratingAtIndexBlock)(NSInteger index);

@end

@implementation ZJImageLoopView

- (instancetype)initWithFrame:(CGRect)frame style:(ZJImageLoopViewScrollStyle)style

{

    self = [super initWithFrame:frame];

    if (self) {

        [self setStyle:style];

        

        [self setSubViews];

    }

    return self;

}

-(void)setSubViews{

    CGRect subframe = CGRectMake(0, 0, CGRectGetWidth([self frame]), CGRectGetHeight([self frame]));

    UIScrollView * scroll = [[UIScrollView alloc] initWithFrame:subframe];

    [scroll setBounces:false];

    [scroll setPagingEnabled:true];

    [scroll setDelegate:self];

    [scroll setShowsVerticalScrollIndicator:false];

    [scroll setShowsHorizontalScrollIndicator:false];

    [scroll setContentSize:CGSizeMake(CGRectGetWidth([self frame])*3, 0)];

    [scroll setContentOffset:CGPointMake(CGRectGetWidth([self frame]), 0)];

    [self setScrollview:scroll];

    [self addSubview:scroll];

    for(int i=0;i<3;i++){

        UIImageView * subview01 = [[UIImageView alloc] init];

        [subview01 setContentMode:UIViewContentModeScaleAspectFit];

        [scroll addSubview:subview01];

        if(i==0){[self setLeftImgView:subview01];}

        if(i==1){[self setCenterImgView:subview01];}

        if(i==2){[self setRightImgView:subview01];}

//        self.leftImgView.backgroundColor = UIColor.redColor;

//        self.centerImgView.backgroundColor = UIColor.blueColor;

//        self.rightImgView.backgroundColor = UIColor.greenColor;

        self.leftImgView.backgroundColor = UIColor.whiteColor;

        self.centerImgView.backgroundColor = UIColor.whiteColor;

        self.rightImgView.backgroundColor = UIColor.whiteColor;

    }

    [scroll bringSubviewToFront:[self leftImgView]];

    [scroll sendSubviewToBack:[self rightImgView]];

    

    [self allocSubViewsOriginalFrameWithStyle:self.style];

    

    UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapClick)];

    [self addGestureRecognizer:tap];

}

 

#pragma mark -

- (void)scrollViewDidScroll:(UIScrollView *)scrollView{

    @autoreleasepool {

        if(self.style == ZJImageLoopViewScrollStyleJustifyZoom){

            [self styleJustifyZoomWithScrollView:scrollView];

        }else if (self.style == ZJImageLoopViewScrollStyleZoom){

            [self styleZoomWithScrollView:scrollView];

        }

    }

}

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{

    [self handleShowImagesAndrecoveryOriginalFrame];

}

-(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{

    [self handleShowImagesAndrecoveryOriginalFrame];

}

//开始拖动的时候调用

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{

    [self cancelTimer];

}

//结束拖动时调用

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{

    [self openTimer];

}

#pragma mark - 定时器

-(void)openTimer{

    if(self.timer != nil){return;}

    NSTimeInterval time = 2.0;

    // 获得队列

    dispatch_queue_t queue = dispatch_get_main_queue();

    // 创建一个定时器(dispatch_source_t本质还是个OC对象)

    self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);

    // 何时开始执行第一个任务

    dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(time * NSEC_PER_SEC));

    uint64_t interval = (uint64_t)(time * NSEC_PER_SEC);

    dispatch_source_set_timer(self.timer, start, interval, 0);

    // 设置回调

    __weak typeof(self) weakSelf = self;

    dispatch_source_set_event_handler(self.timer, ^{

        if([weakSelf scrollDirection] == 2){

            CGPoint offset = [[weakSelf scrollview] contentOffset];

            offset.x -= CGRectGetWidth([[weakSelf scrollview] frame]);

            [[weakSelf scrollview] setContentOffset:offset animated:true];

        }else if([weakSelf scrollDirection] == 1){

            CGPoint offset = [[weakSelf scrollview] contentOffset];

            offset.x += CGRectGetWidth([[weakSelf scrollview] frame]);

            [[weakSelf scrollview] setContentOffset:offset animated:true];

        }else{

            [weakSelf cancelTimer];

        }

    });

    // 启动定时器

    dispatch_resume(self.timer);

}

/** 销毁定时器*/

-(void)cancelTimer{

    if(self.timer){

        dispatch_cancel(self.timer);

        self.timer = nil;

    }

}

-(void)dealloc{

    [self cancelTimer];

}

#pragma mark - 处理索、图片、坐标

-(void)handleShowImagesAndrecoveryOriginalFrame{

    // 处理当前索引

    [self handleCurrentIndex];

    

    // 处理图片

    [self handleScrollImageViewWithNewImage];

    

    // 恢复坐标

    [self recoverySubViewsOriginalFrame];

    // 回调

    if([self didEndDeceleratingAtIndexBlock]){

        self.didEndDeceleratingAtIndexBlock([self currentIndex]);

    }

    if([self delegate] && [[self delegate] respondsToSelector:@selector(ZJImageLoopView:didEndDeceleratingAtIndex:)]){

        [[self delegate] ZJImageLoopView:self didEndDeceleratingAtIndex:[self currentIndex]];

    }

}

/// 处理当前索引

-(void)handleCurrentIndex{

    // 计算索引

    CGFloat offetIndex = [[self scrollview] contentOffset].x/CGRectGetWidth([[self scrollview] frame]);

    if(offetIndex == 1){return;}

    if(offetIndex>1){// 右往左滑+1

        [self setCurrentIndex:[self currentIndex]+1];

        if([self currentIndex]>=[[self dataArray] count]){

            // 确保索引范围

            [self setCurrentIndex:0];

        }

    }else if(offetIndex<1){// 左往右滑-1

        [self setCurrentIndex:[self currentIndex]-1];

        if([self currentIndex] <= -1){

            // 确保索引范围

            [self setCurrentIndex:[[self dataArray] count]-1];

        }

    }

}

/// 处理图片

- (void)handleScrollImageViewWithNewImage{

    [self handleLeftImageViewWithIndex:[self currentIndex]-1];

    [self handleCenterImageViewWithIndex:[self currentIndex]];

    [self handleRightImageViewWithIndex:[self currentIndex]+1];

}

/// 处理左边imgview

-(void)handleLeftImageViewWithIndex:(NSInteger)index{

    NSString * string = @"";

    if (index < 0) {

        string = self.dataArray.lastObject;

    }else if (index < self.dataArray.count){

        string = [self.dataArray objectAtIndex:index];

    }

    [self imageView:self.leftImgView imageString:string];

}

/// 处理中间imgview

-(void)handleCenterImageViewWithIndex:(NSInteger)index{

    NSString * string = @"";

    if (index < self.dataArray.count){

        string = [self.dataArray objectAtIndex:index];

    }

    [self imageView:self.centerImgView imageString:string];

}

/// 处理右边imgview

-(void)handleRightImageViewWithIndex:(NSInteger)index{

    NSString * string = @"";

    if (index >= self.dataArray.count) {

        string = self.dataArray.firstObject;

    }else if (index >= 0){

        string = [self.dataArray objectAtIndex:index];

    }

    [self imageView:self.rightImgView imageString:string];

}

/// 加载图片

-(void)imageView:(UIImageView*)imgView imageString:(NSString*)string{

    if([string containsString:@"http"]){// 网络图片

    }else if([string containsString:@"/"]){// 路径图片

        [imgView setImage:[UIImage imageWithContentsOfFile:string]];

    }else {// 本地图片名称

        [imgView setImage:[UIImage imageNamed:string]];

    }

}

#pragma mark - 位置

/// 初始化位置

-(void)allocSubViewsOriginalFrameWithStyle:(ZJImageLoopViewScrollStyle)style{

    if(style == ZJImageLoopViewScrollStyleNone){

        [self originalFrameWithStyleNone];

    }else if(style == ZJImageLoopViewScrollStyleZoom){

        [self originalFrameWithStyleZoom];

    }else if(style == ZJImageLoopViewScrollStyleJustifyZoom){

        [self originalFrameWithStyleJustifyZoom];

    }

}

-(void)originalFrameWithStyleNone{

    CGFloat width  = CGRectGetWidth(self.scrollview.frame);

    CGFloat height = CGRectGetHeight(self.scrollview.frame);

    self.originalcentertFrame = CGRectMake(width, 0, width, height);

    self.centerImgView.frame  = self.originalcentertFrame;

    

    self.originalleftFrame = CGRectMake(0, 0, width, height);

    self.leftImgView.frame = self.originalleftFrame;

    

    self.originalrightFrame = CGRectMake(width*2, 0, width, height);

    self.rightImgView.frame = self.originalrightFrame;

}

-(void)originalFrameWithStyleZoom{

    [self originalFrameWithStyleNone];

}

-(void)originalFrameWithStyleJustifyZoom{

    CGFloat margin = 30;

    CGFloat centerX = CGRectGetWidth(self.scrollview.frame)*1.5;

    CGFloat centerY = CGRectGetHeight(self.scrollview.frame)*0.5;

    CGFloat width  = (CGRectGetWidth(self.scrollview.frame)-margin*2);

    CGFloat height = (CGRectGetWidth(self.scrollview.frame)*0.7-40);

    

    self.originalcentertFrame = CGRectMake(centerX-width*0.5, centerY-height*0.5, width, height);

    self.centerImgView.frame  = self.originalcentertFrame;

    

    height -= 60;

    width = self.originalcentertFrame.size.width/self.originalcentertFrame.size.height * height;

    centerX = CGRectGetMinX(self.centerImgView.frame) - margin*0.5 - width*0.5;

    

    self.originalleftFrame = CGRectMake(centerX-width*0.5, centerY-height*0.5, width, height);

    self.leftImgView.frame = self.originalleftFrame;

    

    centerX = CGRectGetMaxX(self.centerImgView.frame) + margin*0.5 + width*0.5;

    self.originalrightFrame = CGRectMake(centerX-width*0.5, centerY-height*0.5, width, height);

    self.rightImgView.frame = self.originalrightFrame;

}

/// 恢复初始化位置

-(void)recoverySubViewsOriginalFrame{

    self.leftImgView.frame = self.originalleftFrame;

    self.centerImgView.frame = self.originalcentertFrame;

    self.rightImgView.frame = self.originalrightFrame;

    // 保证中心位置

    [self.scrollview setContentOffset:CGPointMake(CGRectGetWidth([self.scrollview frame]), 0)];

}

#pragma mark - 点击图片

-(void)tapClick{

    if([self delegate] && [[self delegate] respondsToSelector:@selector(ZJImageLoopView:didSelectSubviewAtIndex:)]){

        [[self delegate] ZJImageLoopView:self didSelectSubviewAtIndex:[self currentIndex]];

    }

    if([self didSelectSubviewAtIndexBlock]){

        self.didSelectSubviewAtIndexBlock([self currentIndex]);

    }

}

#pragma mark - 外界方法

- (void)showImagesWithImageStrs:(NSArray<NSString*>*)imageStrs{

    if(imageStrs.count<1){return;}

    [self setDataArray:imageStrs];

    [self setCurrentIndex:0];

    // 处理图片

    [self handleScrollImageViewWithNewImage];

    

    ///

    [self showDefaultCurrentIndex:[self currentIndex]];

    if([self scrollDirection] && [self scrollDirection] != 0){

        [self openTimer];

    }else{

        [self cancelTimer];

    }

}

- (void)showDefaultCurrentIndex:(NSInteger)currentIndex{

    [self setCurrentIndex:currentIndex];

    

    [self handleScrollImageViewWithNewImage];

    

}

- (void)didSelectSubviewAtIndex:(void(^)(NSInteger index))block{

    [self setDidSelectSubviewAtIndexBlock:block];

}

 

- (void)didEndDeceleratingAtIndex:(void(^)(NSInteger index))block{

    [self setDidEndDeceleratingAtIndexBlock:block];

}

#pragma mark - 样式 styleZoom

-(void)styleZoomWithScrollView:(UIScrollView*)scroll{

   

    CGFloat offset = scroll.contentOffset.x;

    CGSize size  = self.frame.size;

    CGFloat scale = 0.6;

    if(offset>CGRectGetWidth([self frame])){// 从右往左

        CGRect subFrame = CGRectMake(0, 0, size.width*scale, 0);

        CGPoint center = CGPointMake(size.width*0.5+offset, size.height*0.5);

        subFrame.size.width += (offset-size.width*1.0)*(1-scale);

        subFrame.size.height = size.height*subFrame.size.width/size.width;

        [[self rightImgView] setFrame:subFrame];

        [[self rightImgView] setCenter:center];

        [[self leftImgView] setCenter:CGPointMake(size.width*0.5, size.height*0.5)];

    }else{// 从左往右

        CGRect subFrame = CGRectMake(0, 0, size.width, size.height);

        CGPoint center = CGPointMake(size.width*0.5+offset, size.height*0.5);

        subFrame.size.width -= (size.width-offset)*(1-scale);

        subFrame.size.height = size.height*subFrame.size.width/size.width;

        [[self centerImgView] setFrame:subFrame];

        [[self centerImgView] setCenter:center];

        [[self rightImgView] setCenter:CGPointMake(size.width*2.5, size.height*0.5)];

    }

}

#pragma mark - 样式 styleJustifyZoom

-(void)styleJustifyZoomWithScrollView:(UIScrollView*)scroll{

    CGFloat offset = scroll.frame.size.width - scroll.contentOffset.x;

     if(offset>0) {// 从左往右

         [self JustifyZoomLeftToRightWithChangeValue:offset];

     }else{

         [self JustifyZoomRightToLeftWithChangeValue:offset];

     }

}

/// styleZoom从左往右

-(void)JustifyZoomLeftToRightWithChangeValue:(CGFloat)offset{

    self.leftImgView.frame = [self JustifyZoomEnlargeWithOriginalFrame:self.originalleftFrame changeValue:offset];

    

    self.centerImgView.frame = [self JustifyZoomNarrowWithOriginalFrame:self.originalcentertFrame changeValue:offset];

}

/// styleJustifyZoom从右往左

-(void)JustifyZoomRightToLeftWithChangeValue:(CGFloat)offset{

    self.rightImgView.frame = [self JustifyZoomEnlargeWithOriginalFrame:self.originalrightFrame changeValue:-offset];

    

    self.centerImgView.frame = [self JustifyZoomNarrowWithOriginalFrame:self.originalcentertFrame changeValue:-offset];

}

/// 放大坐标

-(CGRect)JustifyZoomEnlargeWithOriginalFrame:(CGRect)frame changeValue:(CGFloat)value{

    CGFloat max = self.originalcentertFrame.size.height;

    CGFloat centerX = frame.origin.x+frame.size.width*0.5;

    CGFloat centerY = frame.origin.y+frame.size.height*0.5;

    CGFloat H = (frame.size.height + value) > max ? max : (frame.size.height + value);

    CGFloat W = frame.size.width/frame.size.height * H;

    CGRect newFrame = CGRectMake(centerX-W*0.5, centerY-H*0.5, W, H);

    return  newFrame;

}

/// 缩小坐标

-(CGRect)JustifyZoomNarrowWithOriginalFrame:(CGRect)frame changeValue:(CGFloat)value{

    CGFloat min = self.originalleftFrame.size.height;

    CGFloat centerX = frame.origin.x+frame.size.width*0.5;

    CGFloat centerY = frame.origin.y+frame.size.height*0.5;

    CGFloat H = (frame.size.height - value) < min ? min : (frame.size.height - value);

    CGFloat W = frame.size.width/frame.size.height * H;

    CGRect newFrame = CGRectMake(centerX-W*0.5, centerY-H*0.5, W, H);

    return  newFrame;

}

@end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值