Full Code of Delyer/JYCarousel for AI

master 76043c54e5c5 cached
45 files
101.0 KB
30.3k tokens
1 symbols
1 requests
Download .txt
Repository: Delyer/JYCarousel
Branch: master
Commit: 76043c54e5c5
Files: 45
Total size: 101.0 KB

Directory structure:
gitextract_i9tucx6a/

├── .gitignore
├── JYCarousel/
│   ├── App/
│   │   ├── AppDelegate.h
│   │   └── AppDelegate.m
│   ├── Assets.xcassets/
│   │   ├── AppIcon.appiconset/
│   │   │   └── Contents.json
│   │   ├── Contents.json
│   │   ├── default.imageset/
│   │   │   └── Contents.json
│   │   └── images/
│   │       ├── 1.imageset/
│   │       │   └── Contents.json
│   │       ├── 2.imageset/
│   │       │   └── Contents.json
│   │       ├── 3.imageset/
│   │       │   └── Contents.json
│   │       ├── 4.imageset/
│   │       │   └── Contents.json
│   │       ├── 5.imageset/
│   │       │   └── Contents.json
│   │       └── Contents.json
│   ├── Base.lproj/
│   │   └── LaunchScreen.storyboard
│   ├── Info.plist
│   ├── JYCarousel/
│   │   ├── JYCarousel.h
│   │   ├── JYCarousel.m
│   │   ├── JYConfiguration.h
│   │   ├── JYConfiguration.m
│   │   ├── JYImageCache.h
│   │   ├── JYImageCache.m
│   │   ├── JYImageDownloader.h
│   │   ├── JYImageDownloader.m
│   │   ├── JYPageControl.h
│   │   ├── JYPageControl.m
│   │   ├── JYTitleLabel.h
│   │   ├── JYTitleLabel.m
│   │   ├── JYWeakTimer.h
│   │   ├── JYWeakTimer.m
│   │   ├── UIImageView+JYImageViewManager.h
│   │   └── UIImageView+JYImageViewManager.m
│   ├── ViewController/
│   │   ├── CarouselTableViewCell.h
│   │   ├── CarouselTableViewCell.m
│   │   ├── CarouselTableViewCell.xib
│   │   ├── DemoViewController.h
│   │   ├── DemoViewController.m
│   │   ├── DemoViewController.xib
│   │   ├── RootViewController.h
│   │   ├── RootViewController.m
│   │   └── RootViewController.xib
│   └── main.m
├── JYCarousel.podspec
├── JYCarousel.xcodeproj/
│   ├── project.pbxproj
│   └── project.xcworkspace/
│       └── contents.xcworkspacedata
├── LICENSE
└── README.md

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
# Xcode
#
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore

## Build generated
.DS_Store
build/
DerivedData/
fir_build/
.idea/
compile_commands.json
#ProvisioningProfiles/
## Various settings
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata

## Other
*.xccheckout
*.moved-aside
*.xcuserstate
*.xcscmblueprint
*.xcscheme

## Obj-C/Swift specific
*.hmap
*.ipa

# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
#
Pods/
#Podfile
#Podfile.lock

# Carthage
#
# Add this line if you want to avoid checking in source code from Carthage dependencies.
# Carthage/Checkouts

Carthage/Build

# fastlane
#
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 
# screenshots whenever they are needed.
# For more information about the recommended setup visit:
# https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md

fastlane/report.xml
fastlane/screenshots
Preview.html
#svn
.svn/

================================================
FILE: JYCarousel/App/AppDelegate.h
================================================
//
//  AppDelegate.h
//  JYCarousel
//
//  Created by Dely on 16/11/14.
//  Copyright © 2016年 Dely. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;


@end



================================================
FILE: JYCarousel/App/AppDelegate.m
================================================
//
//  AppDelegate.m
//  JYCarousel
//
//  Created by Dely on 16/11/14.
//  Copyright © 2016年 Dely. All rights reserved.
//

#import "AppDelegate.h"
#import "RootViewController.h"
#import "JYImageCache.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.backgroundColor = [UIColor whiteColor];
    
    RootViewController *vc = [[RootViewController alloc] init];
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
    self.window.rootViewController = nav;
    [self.window makeKeyAndVisible];
    
    //每次启动时,检查是否超时,清除缓存(单位是小时这里是10分钟)
    [[JYImageCache sharedImageCache] jy_clearDiskCachesWithTimeout:10.0/60];
    
    return YES;
}


- (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}


- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}


- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}


- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}


- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}


@end


================================================
FILE: JYCarousel/Assets.xcassets/AppIcon.appiconset/Contents.json
================================================
{
  "images" : [
    {
      "idiom" : "iphone",
      "size" : "20x20",
      "scale" : "2x"
    },
    {
      "idiom" : "iphone",
      "size" : "20x20",
      "scale" : "3x"
    },
    {
      "idiom" : "iphone",
      "size" : "29x29",
      "scale" : "2x"
    },
    {
      "idiom" : "iphone",
      "size" : "29x29",
      "scale" : "3x"
    },
    {
      "idiom" : "iphone",
      "size" : "40x40",
      "scale" : "2x"
    },
    {
      "idiom" : "iphone",
      "size" : "40x40",
      "scale" : "3x"
    },
    {
      "idiom" : "iphone",
      "size" : "60x60",
      "scale" : "2x"
    },
    {
      "idiom" : "iphone",
      "size" : "60x60",
      "scale" : "3x"
    },
    {
      "idiom" : "ipad",
      "size" : "20x20",
      "scale" : "1x"
    },
    {
      "idiom" : "ipad",
      "size" : "20x20",
      "scale" : "2x"
    },
    {
      "idiom" : "ipad",
      "size" : "29x29",
      "scale" : "1x"
    },
    {
      "idiom" : "ipad",
      "size" : "29x29",
      "scale" : "2x"
    },
    {
      "idiom" : "ipad",
      "size" : "40x40",
      "scale" : "1x"
    },
    {
      "idiom" : "ipad",
      "size" : "40x40",
      "scale" : "2x"
    },
    {
      "idiom" : "ipad",
      "size" : "76x76",
      "scale" : "1x"
    },
    {
      "idiom" : "ipad",
      "size" : "76x76",
      "scale" : "2x"
    },
    {
      "idiom" : "ipad",
      "size" : "83.5x83.5",
      "scale" : "2x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}

================================================
FILE: JYCarousel/Assets.xcassets/Contents.json
================================================
{
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}

================================================
FILE: JYCarousel/Assets.xcassets/default.imageset/Contents.json
================================================
{
  "images" : [
    {
      "idiom" : "universal",
      "scale" : "1x"
    },
    {
      "idiom" : "universal",
      "filename" : "default@2x.png",
      "scale" : "2x"
    },
    {
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}

================================================
FILE: JYCarousel/Assets.xcassets/images/1.imageset/Contents.json
================================================
{
  "images" : [
    {
      "idiom" : "universal",
      "filename" : "1.jpg",
      "scale" : "1x"
    },
    {
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}

================================================
FILE: JYCarousel/Assets.xcassets/images/2.imageset/Contents.json
================================================
{
  "images" : [
    {
      "idiom" : "universal",
      "filename" : "2.jpg",
      "scale" : "1x"
    },
    {
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}

================================================
FILE: JYCarousel/Assets.xcassets/images/3.imageset/Contents.json
================================================
{
  "images" : [
    {
      "idiom" : "universal",
      "filename" : "3.jpg",
      "scale" : "1x"
    },
    {
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}

================================================
FILE: JYCarousel/Assets.xcassets/images/4.imageset/Contents.json
================================================
{
  "images" : [
    {
      "idiom" : "universal",
      "filename" : "4.jpg",
      "scale" : "1x"
    },
    {
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}

================================================
FILE: JYCarousel/Assets.xcassets/images/5.imageset/Contents.json
================================================
{
  "images" : [
    {
      "idiom" : "universal",
      "filename" : "5.jpg",
      "scale" : "1x"
    },
    {
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}

================================================
FILE: JYCarousel/Assets.xcassets/images/Contents.json
================================================
{
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}

================================================
FILE: JYCarousel/Base.lproj/LaunchScreen.storyboard
================================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="11134" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11106"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <scenes>
        <!--View Controller-->
        <scene sceneID="EHf-IW-A2E">
            <objects>
                <viewController id="01J-lp-oVM" sceneMemberID="viewController">
                    <layoutGuides>
                        <viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/>
                        <viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
                    </layoutGuides>
                    <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                    </view>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="53" y="375"/>
        </scene>
    </scenes>
</document>


================================================
FILE: JYCarousel/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleDevelopmentRegion</key>
	<string>en</string>
	<key>CFBundleDisplayName</key>
	<string>JYCarousel</string>
	<key>CFBundleExecutable</key>
	<string>$(EXECUTABLE_NAME)</string>
	<key>CFBundleIdentifier</key>
	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>
	<string>$(PRODUCT_NAME)</string>
	<key>CFBundlePackageType</key>
	<string>APPL</string>
	<key>CFBundleShortVersionString</key>
	<string>1.0</string>
	<key>CFBundleVersion</key>
	<string>1</string>
	<key>LSRequiresIPhoneOS</key>
	<true/>
	<key>NSAppTransportSecurity</key>
	<dict>
		<key>NSAllowsArbitraryLoads</key>
		<true/>
	</dict>
	<key>UILaunchStoryboardName</key>
	<string>LaunchScreen</string>
	<key>UIRequiredDeviceCapabilities</key>
	<array>
		<string>armv7</string>
	</array>
	<key>UISupportedInterfaceOrientations</key>
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationLandscapeLeft</string>
		<string>UIInterfaceOrientationLandscapeRight</string>
	</array>
	<key>UISupportedInterfaceOrientations~ipad</key>
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationPortraitUpsideDown</string>
		<string>UIInterfaceOrientationLandscapeLeft</string>
		<string>UIInterfaceOrientationLandscapeRight</string>
	</array>
</dict>
</plist>


================================================
FILE: JYCarousel/JYCarousel/JYCarousel.h
================================================
//
//  JYCarousel.h
//  JYCarousel
//
//  Created by Dely on 16/11/14.
//  Copyright © 2016年 Dely. All rights reserved.
//

/*
 * 这是一个使用起来非常简单的开源库,自带下载缓存,不会造成循环引用,不用考虑定时器不会销毁(我都已经帮你做好了)
 * 如果使用过程中有任何问题,可以联系我,我会第一时间回复你,然后尽我的努力把这个库维护的更好,更简单方便的使用。
 * 谢谢支持,如果喜欢,请给我个star。
 *
 * 作者:Delyer
 * 简书:http://www.jianshu.com/users/e95705fe04d9    (现在写博客的主要地方)
 * 个人博客:http://dely.vip
 * github:https://github.com/Delyer
 * 邮箱:jiayaoit@126.com
 * 微信:Delyer521
 */

#import <UIKit/UIKit.h>
#import "JYConfiguration.h"
#import "JYPageControl.h"
#import "JYTitleLabel.h"


@protocol JYCarouselDelegate <NSObject>

@optional
- (void)carouselViewClick:(NSInteger)index;

@end

@interface JYCarousel : UIView

#pragma mark - ==============初始化==============

/**
 block方式回调初始化

 @param frame       frame
 @param configBlock 轮播属性配置(可以为nil,为nil时采用默认的配置)
 @param clickBlock  点击回调

 @return carousel
 */
- (instancetype)initWithFrame:(CGRect)frame
                  configBlock:(CarouselConfigurationBlock)configBlock
                   clickBlock:(CarouselClickBlock)clickBlock;


/**
 delegate方式回调初始化
 
 @param frame       frame
 @param configBlock 轮播属性配置(可以为nil,为nil时采用默认的配置)
 @param target      delegate
 
 @return carousel
 */
- (instancetype)initWithFrame:(CGRect)frame
                  configBlock:(CarouselConfigurationBlock)configBlock
                       target:(id<JYCarouselDelegate>)target;




#pragma mark - ==============开始轮播==============


/*
 start Carousel
 imageArray(里面可以存放UIImage对象、NSString对象【本地图片名】、NSURL对象【远程图片的URL】)
 titleArray 标题
 */
- (void)startCarouselWithArray:(NSMutableArray *)imageArray;
- (void)startCarouselWithArray:(NSMutableArray *)imageArray titleArray:(NSMutableArray *)titleArray;


/*
 start Carousel With new Config(更新轮播配置,新的样式轮播)
 configBlock 轮播属性配置(可以为nil,为nil时采用之前默认的配置)
 titleArray 标题
 */
- (void)startCarouselWithNewConfig:(CarouselConfigurationBlock)configBlock array:(NSMutableArray *)imageArray;
- (void)startCarouselWithNewConfig:(CarouselConfigurationBlock)configBlock array:(NSMutableArray *)imageArray titleArray:(NSMutableArray *)titleArray;



@end


================================================
FILE: JYCarousel/JYCarousel/JYCarousel.m
================================================
//
//  JYCarousel.m
//  JYCarousel
//
//  Created by Dely on 16/11/14.
//  Copyright © 2016年 Dely. All rights reserved.
//

/*
 三张图A、B、C你要做的scrollview实际上应该是五张的大小顺序是C、A、B、C、A。初始偏移量设置到第二张,监听scrollview滑动事件。判断偏移量。当偏移量在第一张时将偏移量修改到第四张,当偏移量在第五张时将偏移量调整到第二章。这样在循环时比较流畅
 */

#import "JYCarousel.h"
#import "UIImageView+JYImageViewManager.h"
#import "JYWeakTimer.h"

@interface JYCarousel ()<UIScrollViewDelegate>

//图片数据(里面可以存放UIImage对象、NSString对象【本地图片名】、NSURL对象【远程图片的URL】)
@property (strong, nonatomic) NSMutableArray *images;

//title数据
@property (strong, nonatomic) NSMutableArray *titles;

#pragma mark -----------私有属性-------------------

@property (nonatomic, strong) UIScrollView  *scrollView;

//存放3个imageView的数值
@property (nonatomic, strong) NSMutableArray *imageViewArray;

//点击block
@property (nonatomic, copy) CarouselClickBlock clickBlock;

//当前显示视图索引
@property (nonatomic, assign) NSInteger imageIndex;

@property (nonatomic, strong) JYConfiguration *config;

@property (nonatomic, strong) JYPageControl *pageControl;

@property (nonatomic, strong) JYTitleLabel *titleLabel;

@property (nonatomic, strong) NSTimer *timer;

//是否自动轮播,默认是轮播的
@property (nonatomic, assign) BOOL isAutoPlay;

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

@end


@implementation JYCarousel

- (NSMutableArray *)imageViewArray{
    if (!_imageViewArray) {
        _imageViewArray =[[NSMutableArray alloc] init];
    }
    return _imageViewArray;
}

- (NSMutableArray *)titles{
    if (!_titles) {
        _titles =[[NSMutableArray alloc] init];
    }
    return _titles;
}

#pragma mark -----------初始化-------------------

- (instancetype)initWithFrame:(CGRect)frame configBlock:(CarouselConfigurationBlock)configBlock clickBlock:(CarouselClickBlock)clickBlock{
    self = [super initWithFrame:frame];
    if (self) {
        self.imageIndex = 0;
        if (configBlock) {
            JYConfiguration *configurate = [[JYConfiguration alloc] init];
            configurate.interValTime = DefaultTime;
            configurate.titleFont = DefaultTitileFont;
            self.config = configBlock(configurate);
        }else{
            self.config = [[JYConfiguration alloc] init];
            self.config.interValTime = DefaultTime;
            self.config.titleFont = DefaultTitileFont;
        }
        if (clickBlock) {
            __weak __typeof__(clickBlock) weakClickBlock = clickBlock;
            self.clickBlock = weakClickBlock;
        }
        [self initSelfView];
        [self updateSelfView];
    }
    return self;
}


- (instancetype)initWithFrame:(CGRect)frame configBlock:(CarouselConfigurationBlock)configBlock target:(id<JYCarouselDelegate>)target{
    self = [super initWithFrame:frame];
    if (self) {
        self.imageIndex = 0;
        self.delegate = target;
        if (configBlock) {
            JYConfiguration *configurate = [[JYConfiguration alloc] init];
            configurate.interValTime = DefaultTime;
            configurate.titleFont = DefaultTitileFont;
            self.config = configBlock(configurate);
        }else{
            self.config = [[JYConfiguration alloc] init];
            self.config.interValTime = DefaultTime;
            self.config.titleFont = DefaultTitileFont;
        }
        [self initSelfView];
        [self updateSelfView];
    }
    return self;
}

- (void)initSelfView{

    if (!self.pageControl) {
        self.pageControl = [[JYPageControl alloc] init];
    }
    
    if (!self.titleLabel) {
        self.titleLabel = [[JYTitleLabel alloc] init];
    }
    
    [self addSubView];
}

- (void)updateSelfView{
    
    for (UIImageView *imageView in self.imageViewArray) {
        imageView.contentMode = self.config.contentMode;
        imageView.reloadTimesForFailedURL = self.config.faileReloadTimes;
    }
}

//添加scrollView和imageView
- (void)addSubView{
    
    if(_scrollView == nil) {
        UIView *firstView = [[UIView alloc] init];
        [self addSubview:firstView];
        //scrollView
        _scrollView = [[UIScrollView alloc]initWithFrame:self.bounds];
        _scrollView.pagingEnabled = YES;
        _scrollView.bounces = NO;
        _scrollView.showsHorizontalScrollIndicator = NO;
        _scrollView.showsVerticalScrollIndicator = NO;
        _scrollView.delegate = self;
        [self addSubview:_scrollView];
        
        _scrollView.contentSize = CGSizeMake(ViewWidth(_scrollView) *AllImageViewCount, 0);
        _scrollView.contentOffset = CGPointMake(ViewWidth(_scrollView), 0);
        
        //imageView
        for(NSInteger i = 0; i < AllImageViewCount; i++) {
            UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(i * ViewWidth(_scrollView), 0, ViewWidth(_scrollView), ViewHeight(_scrollView))];
            imageView.userInteractionEnabled = YES;
            imageView.contentMode = self.config.contentMode;
            imageView.reloadTimesForFailedURL = self.config.faileReloadTimes;
            [_scrollView addSubview:imageView];
            [imageView addGestureRecognizer:[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(imageClick:)]];
            
            [self.imageViewArray addObject:imageView];
        }
    }
}

// 设置scrollView的contentSize
- (void)setupScrollViewContentSize{
    if(self.images.count > 3){
        self.scrollView.contentSize = CGSizeMake(ViewWidth(_scrollView) *AllImageViewCount, 0);
        self.scrollView.contentOffset = CGPointMake(ViewWidth(_scrollView), 0);
        
    }else{
        self.scrollView.contentSize = CGSizeZero;
        self.scrollView.contentOffset =CGPointZero;
    }
}

- (void)updateConfigWithBlock:(CarouselConfigurationBlock)configBlock{
    JYConfiguration *configurate = self.config;
    if (configBlock) {
        self.config = configBlock(configurate);
        [self updateSelfView];
    }
}


//开始轮播
- (void)startCarouselWithArray:(NSMutableArray *)imageArray{
    self.images = imageArray;
}

- (void)startCarouselWithArray:(NSMutableArray *)imageArray titleArray:(NSMutableArray *)titleArray{
    self.titles = titleArray;
    self.images = imageArray;
}

//开始轮播(以新的轮播样式来运行)
- (void)startCarouselWithNewConfig:(CarouselConfigurationBlock)configBlock array:(NSMutableArray *)imageArray{
    if (!self.config) {
        self.config = [[JYConfiguration alloc] init];
    }
    JYConfiguration *configurate = self.config;
    if (configBlock) {
        self.config = configBlock(configurate);
        [self updateSelfView];
    }
    
    [self startCarouselWithArray:imageArray];
}

- (void)startCarouselWithNewConfig:(CarouselConfigurationBlock)configBlock array:(NSMutableArray *)imageArray titleArray:(NSMutableArray *)titleArray{
    if (!self.config) {
        self.config = [[JYConfiguration alloc] init];
    }
    JYConfiguration *configurate = self.config;
    if (configBlock) {
        self.config = configBlock(configurate);
        [self updateSelfView];
    }
    
    [self startCarouselWithArray:imageArray titleArray:titleArray];
}

#pragma mark - -----------set方法-------------------
- (void)setImages:(NSMutableArray *)images{

    NSInteger num = images.count;
    if (images.count > 0) {
        id firstObj = [images firstObject];
        id lastObj = [images lastObject];
        [images insertObject:lastObj atIndex:0];
        [images insertObject:firstObj atIndex:images.count];
    }
    
    if (!_images) {
        _images = [NSMutableArray array];
    }
    _images = images;
    self.imageIndex = 1;
    [self.titleLabel initViewWithConfiguration:self.config addInView:self];
    [self.pageControl initViewWithNumberOfPages:num configuration:self.config addInView:self];
    [self updateImageViewContent];
    [self setupScrollViewContentSize];
    
    //销毁定时器
    [self stopTimer];
    if (num == 0) {
        self.isAutoPlay = NO;
    }else if (num == 1){
        self.isAutoPlay = NO;
    }else{
        self.isAutoPlay = YES;
        [self beginTimer];
    }
}

#pragma mark - -----------更新图片-------------------

- (void)updateImageViewContent{
    
    if (self.images.count > 2) {
        for (NSInteger i = 0; i < self.imageViewArray.count; i++) {
            UIImageView *imageView = [self.imageViewArray objectAtIndex:i];
            NSInteger imageIndex = 0;
            if (i == 0) { // 左边
                imageIndex = self.imageIndex - 1;
                if (imageIndex == -1) { // 显示最后面一张图片
                    imageIndex = self.images.count - 2;
                }
            } else if (i == 1) { // 中间
                imageIndex = self.imageIndex;
            } else if (i == 2) { // 右边
                imageIndex = self.imageIndex + 1;
                if (imageIndex == self.images.count) { // 显示最前面一张图片
                    imageIndex = 1;
                }
            }
            imageView.tag = imageIndex;
            [self loadImage:imageIndex withImageView:imageView];
        }
        //更新pageControll
        [self.pageControl updateCurrentPageWithIndex:(self.imageIndex-1)];
        
        NSString *title;
        if ((self.imageIndex-1) < self.titles.count) {
            title = [self.titles objectAtIndex:(self.imageIndex-1)];
        }
        [self.titleLabel updateCurrentTitleLabelWithTitle:title];
    }
}

- (void)loadImage:(NSInteger)imageIndex withImageView:(UIImageView *)imageView{
    
    id obj = [self.images objectAtIndex:imageIndex];
    
    if ([obj isKindOfClass:[NSString class]]) { // 本地图片名或者urlStr
        imageView.image = [UIImage imageNamed:obj];
        if (imageView.image == nil) {
            [imageView jy_setImageWithURLString:obj placeholder:self.config.placeholder];
        }
        return;
    }else if ([obj isKindOfClass:[NSURL class]]) { // 远程图片URL
        NSString *URLStr = [obj absoluteString];
        [imageView jy_setImageWithURLString:URLStr placeholder:self.config.placeholder];
        return;
    }else if ([obj isKindOfClass:[UIImage class]]) { // UIImage对象
        imageView.image = obj;
        return;
    }
}


#pragma mark - -------------------视图点击事件-------------------
- (void)imageClick:(UITapGestureRecognizer *)sender{
    __weak typeof(self) weakSelf = self;
    if (self.clickBlock) {
        [self changeImageIndex];
        weakSelf.clickBlock(weakSelf.imageIndex-1);
    }
    
    if (self.delegate && [self.delegate respondsToSelector:@selector(carouselViewClick:)]) {
        [self.delegate carouselViewClick:self.imageIndex-1];
    }
}

#pragma mark - -------------------定时器-------------------
//开始定时器
- (void)beginTimer{
    if ((self.config.interValTime >0) && (self.timer == nil) && self.isAutoPlay) {
        self.timer = [JYWeakTimer scheduledTimerWithTimeInterval:self.config.interValTime target:self selector:@selector(timeAction) userInfo:nil repeats:YES];

        [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
    }
}

//销毁定时器
- (void)stopTimer{
    if (self.timer) {
        [self.timer invalidate];
        self.timer = nil;
    }
}

/// 暂停
- (void)pauseTimer {
    if (!self.timer.isValid) return;
    [self.timer setFireDate:[NSDate distantFuture]];
}
/// 恢复
- (void)resumeTimer {
    if (!self.timer.isValid) return;
    [self.timer setFireDate:[NSDate date]];
}
/// 多少秒后恢复
- (void)resumeWithTimeInterval:(NSTimeInterval)time {
    if (!self.timer.isValid) return;
    [self.timer setFireDate:[NSDate dateWithTimeIntervalSinceNow:time]];
}

- (void)timeAction{
    [UIView animateWithDuration:0.35 animations:^{
        self.scrollView.contentOffset = CGPointMake(2 *ViewWidth(self.scrollView), 0);
    } completion:^(BOOL finished) {
        [self changeImageIndex];
        [self updateImageViewContent];
        [self setupScrollViewContentSize];
    }];

}

#pragma mark - -------------------UIScrollViewDelegate-------------------
//开始拖拽
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
    //暂停定时器
    [self pauseTimer];
}

//结束拖拽
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
    //恢复定时器
    [self resumeWithTimeInterval:self.config.interValTime];
}

//位置发生变化
// 找出显示在最中间的imageView x值和偏移量x差值最小的imageView,就是显示在最中间的imageView
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {

    UIImageView *middleImageView = nil;
    CGFloat minOffset = MAXFLOAT;

    for (UIImageView *imageView in self.imageViewArray) {
        CGFloat currentOffset = ABS(CGRectGetMinX(imageView.frame) - _scrollView.contentOffset.x);
        if (currentOffset < minOffset){
            minOffset = currentOffset;
            middleImageView = imageView;
        }
        self.imageIndex = middleImageView.tag;
    }
}

//结束滚动
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
    [self changeImageIndex];
    [self updateImageViewContent];
    self.scrollView.contentOffset = CGPointMake(CGRectGetWidth(self.scrollView.frame), 0);
}

- (void)changeImageIndex{
    if (self.imageIndex == 0) {
        self.imageIndex = self.images.count - 2;
    }else if(self.imageIndex == (self.images.count-1)){
        self.imageIndex = 1;
    }
}

- (void)dealloc{
    [self stopTimer];
#ifdef kDebugLog
    NSLog(@"销毁定时器");
#endif
}

@end


================================================
FILE: JYCarousel/JYCarousel/JYConfiguration.h
================================================
//
//  JYConfiguration.h
//  JYCarousel
//
//  Created by Dely on 16/11/14.
//  Copyright © 2016年 Dely. All rights reserved.
//

/*
 * 这是一个使用起来非常简单的开源库,自带下载缓存,不会造成循环引用,不用考虑定时器不会销毁(我都已经帮你做好了)
 * 如果使用过程中有任何问题,可以联系我,我会第一时间回复你,然后尽我的努力把这个库维护的更好,更简单方便的使用。
 * 谢谢支持,如果喜欢,请给我个star。
 *
 * 作者:Delyer
 * 简书:http://www.jianshu.com/users/e95705fe04d9    (现在写博客的主要地方)
 * 个人博客:http://dely.vip
 * github:https://github.com/Delyer
 * 邮箱:jiayaoit@126.com
 * 微信:Delyer521
 */

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

@class JYConfiguration;

//#define kDebugLog (如果想看打印注释放开即可)

//imageView的个数
#define AllImageViewCount 3

//View的宽度
#define ViewWidth(view) CGRectGetWidth(view.frame)
//View的高度
#define ViewHeight(view) CGRectGetHeight(view.frame)

#define JYWeakSelf __weak typeof(self) weakSelf = self

//获取用户自定义属性
typedef JYConfiguration *(^CarouselConfigurationBlock)(JYConfiguration *carouselConfig);

//点击事件block
typedef void (^CarouselClickBlock)(NSInteger index);

//UIPageControl类型
typedef NS_ENUM(NSInteger, CarouselPageControllType) {
    MiddlePageControl = 0,
    LeftPageControl,
    RightPageControl,
    LabelPageControl,
    NonePageControl
};

//定时器默认时间
static NSTimeInterval DefaultTime = 3.0;

//titleLabel默认大小
static CGFloat DefaultTitileFont = 10.0;

@interface JYConfiguration : NSObject

/**
 占位图
 */
@property (nonatomic, strong) UIImage *placeholder;

/**
 轮播时间间隔(默认:3s,当设置为0s时,停止自动轮播)
 */
@property (assign, nonatomic) NSTimeInterval interValTime;

/**
 指示器类型(label和pageContoller样式)
 */
@property (nonatomic, assign) CarouselPageControllType pageContollType;

/**
 指示器填充颜色
 */
@property (strong, nonatomic) UIColor *currentPageTintColor;

/**
 指示器颜色
 */
@property (strong, nonatomic) UIColor *pageTintColor;


/**
 图片填充类型(默认是UIViewContentModeScaleToFill)
 */
@property (nonatomic, assign) UIViewContentMode contentMode;


/**
 imageView加载图片失败重试次数(默认2次)
 */
@property (nonatomic, assign) NSInteger faileReloadTimes;



/**
 titleLabel的frame(默认(0,superViewHeight-20,superViewWidth,20))
 */
@property (nonatomic, assign) CGRect titleFrame;

/**
 titleLabel的font(默认10.0)
 */
@property (nonatomic, assign) CGFloat titleFont;

/**
 titleLabel的对齐模式(默认左对齐)
 */
@property (nonatomic, assign) NSTextAlignment textAlignment;

/**
 titleLabel的backgroundColor(默认黑色透明度0.5)
 */
@property (nonatomic, assign) UIColor *titleBackGroundColor;

/**
 titleLabel的titleColor(默认白色)
 */
@property (nonatomic, assign) UIColor *titleColor;

@end


================================================
FILE: JYCarousel/JYCarousel/JYConfiguration.m
================================================
//
//  JYConfiguration.m
//  JYCarousel
//
//  Created by Dely on 16/11/14.
//  Copyright © 2016年 Dely. All rights reserved.
//

#import "JYConfiguration.h"

@implementation JYConfiguration

@end


================================================
FILE: JYCarousel/JYCarousel/JYImageCache.h
================================================
//
//  JYImageCache.h
//  JYCarousel
//
//  Created by Dely on 16/11/17.
//  Copyright © 2016年 Dely. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

FOUNDATION_EXPORT NSString *const JYDidSettingTime;

//#define kDebugLog

@interface JYImageCache : NSObject

+ (JYImageCache *)sharedImageCache;

@property (nonatomic, strong) NSMutableDictionary *jy_cacheFaileTimesDict;

- (UIImage *)jy_cacheImageForRequest:(NSURLRequest *)request;
- (void)jy_cacheImage:(UIImage *)image forRequest:(NSURLRequest *)request;
- (void)jy_cacheFailRequest:(NSURLRequest *)request;
- (NSUInteger)jy_failTimesForRequest:(NSURLRequest *)request;

- (void)jy_clearCacheFaileTimesDict;
- (void)jy_clearDiskCaches;

/**
 超时清除缓存,可以在App启动时设置,以后就会定时清除轮播的缓存

 @param time 超时时间(单位为h)
 */
- (void)jy_clearDiskCachesWithTimeout:(NSTimeInterval)time;


/**
 修改超时清除缓存的时间

 @param time 重新设定的超时时间(单位为h)
 */
- (void)jy_changeDiskCacheWithTimeout:(NSTimeInterval)time;



@end


================================================
FILE: JYCarousel/JYCarousel/JYImageCache.m
================================================
//
//  JYImageCache.m
//  JYCarousel
//
//  Created by Dely on 16/11/17.
//  Copyright © 2016年 Dely. All rights reserved.
//

#import "JYImageCache.h"
#import <UIKit/UIKit.h>
#import <CommonCrypto/CommonDigest.h>

#define Default_cachePath [NSHomeDirectory() stringByAppendingPathComponent:@"Documents/JYCarouselImages"]

NSString *const JYDidSettingTime = @"JYDidSettingTime";

#pragma mark --------NSString的分类方法-----------
@interface NSString (md5Hash)

+ (NSString *)jy_md5Hash:(NSString *)string;
+ (NSString *)jy_cachePath;
+ (NSString *)jy_keyForRequest:(NSURLRequest *)request;

@end

@implementation NSString (md5Hash)

+ (NSString *)jy_keyForRequest:(NSURLRequest *)request {
    return [NSString stringWithFormat:@"%@_JYCarousel",
            request.URL.absoluteString];
}

+ (NSString *)jy_cachePath {
    return Default_cachePath;
}

+ (NSString *)jy_md5Hash:(NSString *)string {
    if (string) {
        const char *cStr = [string UTF8String];
        unsigned char result[16];
        CC_MD5(cStr, (UInt32) strlen(cStr), result);
        NSString *md5Result = [NSString stringWithFormat:
                               @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
                               result[0], result[1], result[2], result[3],
                               result[4], result[5], result[6], result[7],
                               result[8], result[9], result[10], result[11],
                               result[12], result[13], result[14], result[15]];
        return md5Result;
    }
    return nil;

}

@end

#pragma mark --------cache-----------

@implementation JYImageCache

+ (JYImageCache *)sharedImageCache {
    static JYImageCache *instance;

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[JYImageCache alloc] init];
    });
    return instance;
}


- (NSMutableDictionary *)jy_cacheFaileTimesDict{
    if (!_jy_cacheFaileTimesDict) {
        _jy_cacheFaileTimesDict = [NSMutableDictionary dictionary];
    }
    return _jy_cacheFaileTimesDict;
}

- (void)jy_clearCacheFaileTimesDict{
    [self.jy_cacheFaileTimesDict removeAllObjects];
    self.jy_cacheFaileTimesDict = nil;
}


- (void)jy_clearDiskCaches{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    dispatch_async(queue, ^{
        NSString *directoryPath = [NSString jy_cachePath];
        
        if ([[NSFileManager defaultManager] fileExistsAtPath:directoryPath isDirectory:nil]) {
            NSError *error = nil;
            [[NSFileManager defaultManager] removeItemAtPath:directoryPath error:&error];
        }
        [self jy_clearCacheFaileTimesDict];
    });
   

}

- (UIImage *)jy_cacheImageForRequest:(NSURLRequest *)request{
    if (request) {
        NSString *directoryPath = [NSString jy_cachePath];
        NSString *path = [NSString stringWithFormat:@"%@/%@",
                          directoryPath,
                          [NSString jy_md5Hash:[NSString jy_keyForRequest:request]]];
        return [UIImage imageWithContentsOfFile:path];
    }
    
    return nil;
    
}
- (void)jy_cacheImage:(UIImage *)image forRequest:(NSURLRequest *)request{
    if (image == nil || request == nil) {
        return;
    }
    
    NSString *directoryPath = Default_cachePath;
    
    if (![[NSFileManager defaultManager] fileExistsAtPath:directoryPath isDirectory:nil]) {
        NSError *error = nil;
        [[NSFileManager defaultManager] createDirectoryAtPath:directoryPath
                                  withIntermediateDirectories:YES
                                                   attributes:nil
                                                        error:&error];

        if (error) {
#ifdef kDebugLog
            NSLog(@"create cache dir error: %@", error);
#endif
            return;
        }

    }

    NSString *path = [NSString stringWithFormat:@"%@/%@",
                      directoryPath,
                      [NSString jy_md5Hash:[NSString jy_keyForRequest:request]]];
    NSData *data = UIImagePNGRepresentation(image);
    if (data) {
        BOOL isOk = [[NSFileManager defaultManager] createFileAtPath:path contents:data attributes:nil];
        
        if (isOk) {
#ifdef kDebugLog
            NSLog(@"save file ok for request: %@", [NSString jy_md5Hash:[NSString jy_keyForRequest:request]]);
#endif
        } else {
#ifdef kDebugLog
            NSLog(@"save file error for request: %@", [NSString jy_md5Hash:[NSString jy_keyForRequest:request]]);
#endif
        }
    }
}
- (void)jy_cacheFailRequest:(NSURLRequest *)request{
    
    NSNumber *faileTimes = [self.jy_cacheFaileTimesDict objectForKey:[NSString jy_md5Hash:[NSString jy_keyForRequest:request]]];
    
    if (faileTimes) {
        NSInteger times = 0;
        if (faileTimes && [faileTimes respondsToSelector:@selector(integerValue)]) {
            times = [faileTimes integerValue];
        }
        times++;
        [self.jy_cacheFaileTimesDict setObject:@(times) forKey:[NSString jy_md5Hash:[NSString jy_keyForRequest:request]]];
    }
}

- (NSUInteger)jy_failTimesForRequest:(NSURLRequest *)request{
    
    NSNumber *faileTimes = [self.jy_cacheFaileTimesDict objectForKey:[NSString jy_md5Hash:[NSString jy_keyForRequest:request]]];
    
    if (faileTimes && [faileTimes respondsToSelector:@selector(integerValue)]) {
        return [faileTimes integerValue];
    }
    
    return 0;
}


- (void)jy_clearDiskCachesWithTimeout:(NSTimeInterval)time{
    NSDate *nowDate = [NSDate date];
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    formatter.dateFormat = @"yyyy-MM-dd-HH:mm:ss";
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSString *settingTime = [defaults objectForKey:JYDidSettingTime];
    
    if (!settingTime ||[settingTime isEqualToString:JYDidSettingTime] ) {
        NSTimeInterval  timeInterval = 60*60*time;
        NSDate *tmpDate = [nowDate initWithTimeIntervalSinceNow:timeInterval];
        NSString *string = [formatter stringFromDate:tmpDate];
        [defaults setObject:string forKey:JYDidSettingTime];
        [defaults synchronize];
    }else{
        NSString *nowDateString = [formatter stringFromDate:nowDate];
        if ([settingTime compare:nowDateString] == NSOrderedAscending) {
            //升序,说明时间到了 清除缓存
            dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
            dispatch_async(queue, ^{
                NSString *directoryPath = [NSString jy_cachePath];
                
                if ([[NSFileManager defaultManager] fileExistsAtPath:directoryPath isDirectory:nil]) {
                    NSError *error = nil;
                    [[NSFileManager defaultManager] removeItemAtPath:directoryPath error:&error];
                }
                [self jy_clearCacheFaileTimesDict];
                [defaults setObject:JYDidSettingTime forKey:JYDidSettingTime];
                [defaults synchronize];
            });
        }
    }
}

- (void)jy_changeDiskCacheWithTimeout:(NSTimeInterval)time{
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:JYDidSettingTime forKey:JYDidSettingTime];
    [defaults synchronize];
    [self jy_clearDiskCachesWithTimeout:time];
}



@end


================================================
FILE: JYCarousel/JYCarousel/JYImageDownloader.h
================================================
//
//  JYImageDownloader.h
//  JYCarousel
//
//  Created by Dely on 16/11/17.
//  Copyright © 2016年 Dely. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>


typedef void (^JYDownLoadDataFinshedBlock)(NSData *data, NSError *error);
typedef void (^JYDownloadProgressBlock)(unsigned long long total, unsigned long long current);
typedef void (^JYCompletionImageBlock)(UIImage *image);

@interface JYImageDownloader : NSObject

@property (nonatomic, strong) NSURLSessionDownloadTask *task;

+ (JYImageDownloader *)sharedDownloader;

- (void)startDownloadImageWithUrl:(NSString *)url
                         progress:(JYDownloadProgressBlock)progress
                         finished:(JYDownLoadDataFinshedBlock)finished;

@end


================================================
FILE: JYCarousel/JYCarousel/JYImageDownloader.m
================================================
//
//  JYImageDownloader.m
//  JYCarousel
//
//  Created by Dely on 16/11/17.
//  Copyright © 2016年 Dely. All rights reserved.
//

#import "JYImageDownloader.h"


@interface JYImageDownloader ()<NSURLSessionDownloadDelegate>

@property (nonatomic, strong) NSURLSession *session;

@property (nonatomic, assign) unsigned long long totalLength;
@property (nonatomic, assign) unsigned long long currentLength;
@property (nonatomic, copy) JYDownloadProgressBlock progressBlock;
@property (nonatomic, copy) JYDownLoadDataFinshedBlock callbackOnFinished;

@end

@implementation JYImageDownloader

+ (JYImageDownloader *)sharedDownloader {
    static JYImageDownloader *instance;

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [self new];
    });
    return instance;
}


- (void)startDownloadImageWithUrl:(NSString *)url
                         progress:(JYDownloadProgressBlock)progress
                         finished:(JYDownLoadDataFinshedBlock)finished {
    self.progressBlock = progress;
    self.callbackOnFinished = finished;
    
    if ([NSURL URLWithString:url] == nil) {
        if (finished) {
            finished(nil, [NSError errorWithDomain:@"Dely"
                                              code:101
                                          userInfo:@{@"errorMessage": @"URL不正确"}]);
        }
        return;
    }
    
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]
                                                           cachePolicy:NSURLRequestReturnCacheDataElseLoad
                                                       timeoutInterval:60];
    [request addValue:@"image/*" forHTTPHeaderField:@"Accept"];
    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    self.session = [NSURLSession sessionWithConfiguration:config
                                                 delegate:self
                                            delegateQueue:queue];
    NSURLSessionDownloadTask *task = [self.session downloadTaskWithRequest:request];
    [task resume];
    self.task = task;
}


#pragma mark ------------NSURLSessionDownloadDelegate--------------

//完成下载
- (void)URLSession:(NSURLSession *)session
      downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)location {
    NSData *data = [NSData dataWithContentsOfURL:location];
    
    if (self.progressBlock) {
        self.progressBlock(self.totalLength, self.currentLength);
    }
    
    if (self.callbackOnFinished) {
        self.callbackOnFinished(data, nil);
        
        // 防止重复调用
        self.callbackOnFinished = nil;
    }
}

//正在下载
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
    self.currentLength = totalBytesWritten;
    self.totalLength = totalBytesExpectedToWrite;
    
    if (self.progressBlock) {
        self.progressBlock(self.totalLength, self.currentLength);
    }
}

//下载失败
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    if ([error code] != NSURLErrorCancelled) {
        if (self.callbackOnFinished) {
            self.callbackOnFinished(nil, error);
        }
        
        self.callbackOnFinished = nil;
    }
}



@end


================================================
FILE: JYCarousel/JYCarousel/JYPageControl.h
================================================
//
//  JYPageControl.h
//  JYCarousel
//
//  Created by Dely on 16/11/16.
//  Copyright © 2016年 Dely. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "JYConfiguration.h"

@interface JYPageControl : NSObject

- (void)initViewWithNumberOfPages:(NSInteger)numberOfPages configuration:(JYConfiguration *)config addInView:(UIView *)superView;

- (void)updateCurrentPageWithIndex:(NSInteger)index;

@end


================================================
FILE: JYCarousel/JYCarousel/JYPageControl.m
================================================
//
//  JYPageControl.m
//  JYCarousel
//
//  Created by Dely on 16/11/16.
//  Copyright © 2016年 Dely. All rights reserved.
//

#import "JYPageControl.h"

//pageControl边距
static CGFloat pageControlMagin = 20.0;

@interface JYPageControl ()

@property (nonatomic, strong) JYConfiguration *config;
@property (nonatomic, assign) CGRect superViewFrame;
@property (nonatomic, strong) UIPageControl *pageControl;
@property (nonatomic, strong) UILabel *pageLabel;
@property (nonatomic, assign) NSInteger numberOfPages;

@end


@implementation JYPageControl

- (void)initViewWithNumberOfPages:(NSInteger)numberOfPages configuration:(JYConfiguration *)config addInView:(UIView *)superView{
    
    self.numberOfPages = numberOfPages;
    self.config = config;
    self.superViewFrame = superView.frame;
    [self removePageControl];
    
    if (self.config.pageContollType == LabelPageControl){
        if (!self.pageLabel && (self.numberOfPages > 1)) {
            self.pageLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetWidth(self.superViewFrame) - 20 - 34, CGRectGetHeight(self.superViewFrame) - 13 -34, 34, 34)];
            self.pageLabel.textAlignment = NSTextAlignmentCenter;
            self.pageLabel.font = [UIFont systemFontOfSize:14.0];
            self.pageLabel.textColor = [UIColor whiteColor];
            self.pageLabel.layer.cornerRadius = 17.0;
            self.pageLabel.layer.masksToBounds = YES;
            self.pageLabel.backgroundColor = [UIColor colorWithWhite:0.5 alpha:0.5];
            self.pageLabel.text = [NSString stringWithFormat:@"%d/%@",1,@(self.numberOfPages)];
            self.pageLabel.layer.zPosition = 1.0;
            [superView addSubview:self.pageLabel];
            
        }else if (self.pageLabel && (self.numberOfPages == 1)){
            //数量为1隐藏label
            [self.pageLabel removeFromSuperview];
            self.pageLabel = nil;
        }
    }else if (self.config.pageContollType != NonePageControl){
        
        if (!self.pageControl && (self.numberOfPages > 0)) {
            self.pageControl = [[UIPageControl alloc] init];
            self.pageControl.hidesForSinglePage = YES;
            self.pageControl.userInteractionEnabled = NO;
            self.pageControl.layer.zPosition = 1.0;
            if (self.config.currentPageTintColor) {
                self.pageControl.currentPageIndicatorTintColor = self.config.currentPageTintColor;
            }
            if (self.config.pageTintColor) {
                self.pageControl.pageIndicatorTintColor = self.config.pageTintColor;
            }
            [superView addSubview:self.pageControl];
        }
        self.pageControl.numberOfPages = _numberOfPages;
        self.pageControl.frame = CGRectMake(0, CGRectGetHeight(self.superViewFrame) - 20, CGRectGetWidth(self.superViewFrame), 20);
        
        CGSize pointSize = [self.pageControl sizeForNumberOfPages:self.numberOfPages];
        CGFloat page_x = (self.pageControl.bounds.size.width - pointSize.width - 2*pageControlMagin) / 2 ;
        
        //设置轮播页码的位置
        if (self.config.pageContollType == LeftPageControl){
            [self.pageControl setBounds:CGRectMake(page_x, self.pageControl.bounds.origin.y, self.pageControl.bounds.size.width, self.pageControl.bounds.size.height)];
            
        }else if (self.config.pageContollType == MiddlePageControl){
            [self.pageControl setBounds:CGRectMake(0, self.pageControl.bounds.origin.y, self.pageControl.bounds.size.width, self.pageControl.bounds.size.height)];
            
        }else if (self.config.pageContollType == RightPageControl){
            [self.pageControl setBounds:CGRectMake(-page_x, self.pageControl.bounds.origin.y, self.pageControl.bounds.size.width, self.pageControl.bounds.size.height)];
        }
        
    }
}

- (void)removePageControl{
    if (self.pageControl) {
        [self.pageControl removeFromSuperview];
        self.pageControl = nil;
    }
    
    if (self.pageLabel) {
        [self.pageLabel removeFromSuperview];
        self.pageLabel = nil;
    }
    
}

- (void)updateCurrentPageWithIndex:(NSInteger)index{
    self.pageControl.currentPage = index;
    self.pageLabel.text = [NSString stringWithFormat:@"%ld/%@",(index+1),@(self.numberOfPages)];
}


@end


================================================
FILE: JYCarousel/JYCarousel/JYTitleLabel.h
================================================
//
//  JYTitleLabel.h
//  JYCarousel
//
//  Created by Dely on 2017/6/13.
//  Copyright © 2017年 Dely. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "JYConfiguration.h"

@interface JYTitleLabel : NSObject

- (void)initViewWithConfiguration:(JYConfiguration *)config addInView:(UIView *)superView;

- (void)updateCurrentTitleLabelWithTitle:(NSString *)title;

@end


================================================
FILE: JYCarousel/JYCarousel/JYTitleLabel.m
================================================
//
//  JYTitleLabel.m
//  JYCarousel
//
//  Created by Dely on 2017/6/13.
//  Copyright © 2017年 Dely. All rights reserved.
//

#import "JYTitleLabel.h"

@interface CustomLabel : UILabel

@property (nonatomic, assign) UIEdgeInsets textInsets;

@end

@implementation CustomLabel

- (instancetype)init {
    if (self = [super init]) {
        _textInsets = UIEdgeInsetsZero;
    }
    return self;
}
- (void)drawTextInRect:(CGRect)rect {
    [super drawTextInRect:UIEdgeInsetsInsetRect(rect, _textInsets)];
}

@end


@interface JYTitleLabel ()

@property (nonatomic, strong) JYConfiguration *config;
@property (nonatomic, assign) CGRect superViewFrame;
@property (nonatomic, strong) CustomLabel *titleLabel;
@property (nonatomic, strong) UIView *titleSuperView;

@end


@implementation JYTitleLabel

- (void)initViewWithConfiguration:(JYConfiguration *)config addInView:(UIView *)superView{
    self.config = config;
    self.superViewFrame = superView.frame;
    self.titleSuperView = superView;
    [self removeTitleView];
    
    if (!self.titleLabel) {
        self.titleLabel = [[CustomLabel alloc] init];
        self.titleLabel.textInsets = UIEdgeInsetsMake(0.f, 5.f, 0.f, 5.f);
        [superView addSubview:self.titleLabel];
    }
    
    if ((CGRectGetWidth(config.titleFrame)>0) && (CGRectGetHeight(config.titleFrame)>0)) {
        self.titleLabel.frame = config.titleFrame;
    }else{
        self.titleLabel.frame = CGRectMake(0, CGRectGetHeight(self.superViewFrame) - 20, CGRectGetWidth(self.superViewFrame), 20);
    }
    
    if (config.titleBackGroundColor) {
        self.titleLabel.backgroundColor = config.titleBackGroundColor;
    }else{
        self.titleLabel.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.4];
    }
    
    self.titleLabel.textAlignment = config.textAlignment;
    
    self.titleLabel.font = [UIFont systemFontOfSize:config.titleFont];
    
    if (config.titleColor) {
        self.titleLabel.textColor = config.titleColor;
    }else{
        self.titleLabel.textColor = [UIColor whiteColor];
    }
}

- (void)removeTitleView{
    if (self.titleLabel) {
        [self.titleLabel removeFromSuperview];
        self.titleLabel = nil;
    }
}

- (void)updateCurrentTitleLabelWithTitle:(NSString *)title{
    if (title) {
        if (!self.titleLabel) {
            [self initViewWithConfiguration:self.config addInView:self.titleSuperView];
        }
        self.titleLabel.text = title;
    }else{
        [self removeTitleView];
    }
}

@end


================================================
FILE: JYCarousel/JYCarousel/JYWeakTimer.h
================================================
//
//  JYWeakTimer.h
//  JYCarousel
//
//  Created by Dely on 16/11/17.
//  Copyright © 2016年 Dely. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface JYWeakTimer : NSObject

+ (NSTimer *) scheduledTimerWithTimeInterval:(NSTimeInterval)interval
                                      target:(id)aTarget
                                    selector:(SEL)aSelector
                                    userInfo:(id)userInfo
                                     repeats:(BOOL)repeats;

@end


================================================
FILE: JYCarousel/JYCarousel/JYWeakTimer.m
================================================
//
//  JYWeakTimer.m
//  JYCarousel
//
//  Created by Dely on 16/11/17.
//  Copyright © 2016年 Dely. All rights reserved.
//

#import "JYWeakTimer.h"

@interface JYWeakTimerTarget : NSObject

@property (nonatomic, weak) id target;
@property (nonatomic, assign) SEL selector;
@property (nonatomic, weak) NSTimer* timer;

@end


@implementation JYWeakTimerTarget

- (void) fire:(NSTimer *)timer {
    if(self.target) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
        [self.target performSelector:self.selector withObject:timer.userInfo afterDelay:0.0f inModes:@[NSRunLoopCommonModes]];
#pragma clang diagnostic pop
    } else {
        [self.timer invalidate];
    }
}

@end

@implementation JYWeakTimer



+ (NSTimer *) scheduledTimerWithTimeInterval:(NSTimeInterval)interval
                                      target:(id)aTarget
                                    selector:(SEL)aSelector
                                    userInfo:(id)userInfo
                                     repeats:(BOOL)repeats {
    JYWeakTimerTarget *timerTarget = [[JYWeakTimerTarget alloc] init];
    timerTarget.target = aTarget;
    timerTarget.selector = aSelector;
    timerTarget.timer = [NSTimer scheduledTimerWithTimeInterval:interval
                                                         target:timerTarget
                                                       selector:@selector(fire:)
                                                       userInfo:userInfo
                                                        repeats:repeats];
    
    return timerTarget.timer;
}


@end


================================================
FILE: JYCarousel/JYCarousel/UIImageView+JYImageViewManager.h
================================================
//
//  UIImageView+JYImageViewManager.h
//  JYCarousel
//
//  Created by Dely on 16/11/17.
//  Copyright © 2016年 Dely. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "JYImageDownloader.h"


@interface UIImageView (JYImageViewManager)

@property (nonatomic, assign) NSInteger reloadTimesForFailedURL;
@property (nonatomic, weak) JYImageDownloader *imageDownLoader;

@property (nonatomic, copy) JYCompletionImageBlock completion;

- (void)jy_setImageWithURLString:(NSString *)url placeholderImage:(NSString *)placeholderImage;
- (void)jy_setImageWithURLString:(NSString *)url placeholder:(UIImage *)placeholderImage;
- (void)jy_setImageWithURLString:(NSString *)url
                  placeholder:(UIImage *)placeholderImage
                   completion:(void (^)(UIImage *image))completion;
- (void)jy_setImageWithURLString:(NSString *)url
             placeholderImage:(NSString *)placeholderImage
                   completion:(void (^)(UIImage *image))completion;


@end


================================================
FILE: JYCarousel/JYCarousel/UIImageView+JYImageViewManager.m
================================================
//
//  UIImageView+JYImageViewManager.m
//  JYCarousel
//
//  Created by Dely on 16/11/17.
//  Copyright © 2016年 Dely. All rights reserved.
//

#import "UIImageView+JYImageViewManager.h"
#import <objc/runtime.h>
#import "JYImageCache.h"

@implementation UIImageView (JYImageViewManager)

//reloadTimesForFailedURL的set和get方法
- (void)setReloadTimesForFailedURL:(NSInteger)reloadTimesForFailedURL{
    SEL key = @selector(reloadTimesForFailedURL);
    objc_setAssociatedObject(self, key, @(reloadTimesForFailedURL), OBJC_ASSOCIATION_RETAIN);
}

- (NSInteger)reloadTimesForFailedURL{
    NSInteger times = [objc_getAssociatedObject(self, _cmd) integerValue];
    
    return (times<=0)?2:times;
}
//imageDownLoader的set和get方法
- (void)setImageDownLoader:(JYImageDownloader *)imageDownLoader{
    SEL key = @selector(imageDownLoader);
    objc_setAssociatedObject(self, key, imageDownLoader, OBJC_ASSOCIATION_RETAIN);
}

- (JYImageDownloader *)imageDownLoader{
    return objc_getAssociatedObject(self, _cmd);
}

//completion的set和get方法
- (void)setCompletion:(JYCompletionImageBlock)completion{
    SEL key = @selector(completion);
    objc_setAssociatedObject(self, key, completion, OBJC_ASSOCIATION_COPY);
}

- (JYCompletionImageBlock)completion{
    return objc_getAssociatedObject(self, _cmd);
}


- (void)setImage:(UIImage *)image isFromCache:(BOOL)isFromCache {
    self.image = image;
    
    if (!isFromCache) {
        CATransition *animation = [CATransition animation];
        [animation setDuration:0.65f];
        [animation setType:kCATransitionFade];
        animation.removedOnCompletion = YES;
        [self.layer addAnimation:animation forKey:@"transition"];
    }
}

- (void)jy_setImageWithURLString:(NSString *)url placeholder:(UIImage *)placeholderImage{
    [self jy_setImageWithURLString:url placeholder:placeholderImage completion:nil];
    
}
- (void)jy_setImageWithURLString:(NSString *)url placeholderImage:(NSString *)placeholderImage{
    UIImage *image = [UIImage imageNamed:placeholderImage];
    [self jy_setImageWithURLString:url placeholder:image completion:nil];
}

- (void)jy_setImageWithURLString:(NSString *)url placeholderImage:(NSString *)placeholderImage completion:(void (^)(UIImage *))completion{
     UIImage *image = [UIImage imageNamed:placeholderImage];
    [self jy_setImageWithURLString:url placeholder:image completion:completion];
}

- (void)jy_setImageWithURLString:(NSString *)url
                  placeholder:(UIImage *)placeholderImage
                   completion:(void (^)(UIImage *image))completion {
    [self.layer removeAllAnimations];
    if (completion) {
        self.completion = completion;
    }
    
    if (url == nil
        || [url isKindOfClass:[NSNull class]]
        || (![url hasPrefix:@"http://"] && ![url hasPrefix:@"https://"])) {
        [self setImage:placeholderImage isFromCache:YES];
        
        if (completion) {
            self.completion(self.image);
        }
        return;
    }
    
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];
    [self downloadWithReqeust:request holder:placeholderImage];
}

- (void)downloadWithReqeust:(NSURLRequest *)theRequest holder:(UIImage *)holder {
    UIImage *cachedImage = [[JYImageCache sharedImageCache] jy_cacheImageForRequest:theRequest];
    
    if (cachedImage) {
        [self setImage:cachedImage isFromCache:YES];
        
        if (self.completion) {
            self.completion(cachedImage);
        }
        return;
    }
    
    [self setImage:holder isFromCache:YES];
    
    
    
    if ([[JYImageCache sharedImageCache] jy_failTimesForRequest:theRequest] >= self.reloadTimesForFailedURL) {
        return;
    }
    
    [self cancelRequest];
    self.imageDownLoader = nil;
    
    __weak __typeof(self) weakSelf = self;
    
    JYImageDownloader *downloader = [[JYImageDownloader alloc] init];
    self.imageDownLoader = downloader;
    [downloader startDownloadImageWithUrl:theRequest.URL.absoluteString progress:nil finished:^(NSData *data, NSError *error) {
        // 成功
        if (data != nil && error == nil) {
            dispatch_async(dispatch_get_global_queue(0, 0), ^{
                UIImage *image = [UIImage imageWithData:data];
                UIImage *finalImage = image;
                
                if (image) {
                    [[JYImageCache sharedImageCache] jy_cacheImage:finalImage forRequest:theRequest];
                } else {

                    [[JYImageCache sharedImageCache] jy_cacheFailRequest:theRequest];
                }
                
                dispatch_async(dispatch_get_main_queue(), ^{
                    if (finalImage) {
                        [weakSelf setImage:finalImage isFromCache:NO];
                        
                        if (weakSelf.completion) {
                            weakSelf.completion(weakSelf.image);
                        }
                    } else {// error data
                        if (weakSelf.completion) {
                            weakSelf.completion(weakSelf.image);
                        }
                    }
                });
            });
        } else { // error
            [[JYImageCache sharedImageCache] jy_cacheFailRequest:theRequest];
            
            if (weakSelf.completion) {
                weakSelf.completion(weakSelf.image);
            }
        }
    }];
}
- (void)cancelRequest{
    [self.imageDownLoader.task cancel];
}


@end


================================================
FILE: JYCarousel/ViewController/CarouselTableViewCell.h
================================================
//
//  CarouselTableViewCell.h
//  JYCarousel
//
//  Created by Dely on 16/11/30.
//  Copyright © 2016年 Dely. All rights reserved.
//

#import <UIKit/UIKit.h>


@interface CarouselTableViewCell : UITableViewCell

- (void)updateViewWithIndexPath:(NSIndexPath*)indexPath;

@end


================================================
FILE: JYCarousel/ViewController/CarouselTableViewCell.m
================================================
//
//  CarouselTableViewCell.m
//  JYCarousel
//
//  Created by Dely on 16/11/30.
//  Copyright © 2016年 Dely. All rights reserved.
//

#import "CarouselTableViewCell.h"
#import "JYCarousel.h"

@interface CarouselTableViewCell ()

@property (nonatomic, strong) JYCarousel *carousel;

@end

@implementation CarouselTableViewCell

- (void)updateViewWithIndexPath:(NSIndexPath*)indexPath{
    NSMutableArray *imageArray2 = [[NSMutableArray alloc] initWithArray: @[@"http://p1.bqimg.com/524586/894925a41a745ba8.jpg",@"http://p1.bqimg.com/524586/edd59898ac21642f.jpg",@"http://p1.bqimg.com/524586/d277aa654cd60c3d.jpg",@"http://p1.bqimg.com/524586/a49b8d3e1b953f25.jpg",@"http://p1.bqimg.com/524586/972bff3b7a5fb7e1.jpg"]];
    
    NSMutableArray *titleArray2 = [[NSMutableArray alloc] initWithArray: @[@"http://p1.bqimg.com/524586/894925a41a745ba8.jpg",@"http://p1.bqimg.com/524586/edd59898ac21642f.jpg",@"http://p1.bqimg.com/524586/d277aa654cd60c3d.jpg",@"http://p1.bqimg.com/524586/a49b8d3e1b953f25.jpg",@"http://p1.bqimg.com/524586/972bff3b7a5fb7e1.jpg"]];
    
    //创建
    if (!_carousel) {
        _carousel = [[JYCarousel alloc] initWithFrame:CGRectMake(0, 0, CGRectGetWidth(self.frame), CGRectGetHeight(self.frame)) configBlock:nil clickBlock:^(NSInteger index) {
            NSLog(@"你点击了第%ld张图片",index);
            //这个类定义协议回调到Viewcontroller
        }];
        [self addSubview:_carousel];
    }
    
    
    //配置轮播样式
    if (indexPath.row <=2) {
        [_carousel startCarouselWithNewConfig:^JYConfiguration *(JYConfiguration *carouselConfig) {
            carouselConfig.pageContollType = MiddlePageControl;
            carouselConfig.pageTintColor = [UIColor whiteColor];
            carouselConfig.currentPageTintColor = [UIColor redColor];
            carouselConfig.placeholder = [UIImage imageNamed:@"default"];
            carouselConfig.faileReloadTimes = 5;
            return carouselConfig;
        } array:imageArray2];
        
    }else{
        
        if (arc4random()%2) {
            [_carousel startCarouselWithNewConfig:^JYConfiguration *(JYConfiguration *carouselConfig) {
                carouselConfig.interValTime = (arc4random()%5)+1;
                carouselConfig.pageContollType = arc4random()%4;
                carouselConfig.currentPageTintColor = [UIColor colorWithRed:(arc4random()%256)/256.0 green:(arc4random()%256)/256.0 blue:(arc4random()%256)/256.0 alpha:1.0];
                carouselConfig.pageTintColor = [UIColor colorWithRed:(arc4random()%256)/256.0 green:(arc4random()%256)/256.0 blue:(arc4random()%256)/256.0 alpha:1.0];
                return carouselConfig;
            } array:imageArray2];
        }else{
            [_carousel startCarouselWithNewConfig:^JYConfiguration *(JYConfiguration *carouselConfig) {
                carouselConfig.interValTime = (arc4random()%5)+1;
                carouselConfig.pageContollType = arc4random()%4;
                carouselConfig.currentPageTintColor = [UIColor colorWithRed:(arc4random()%256)/256.0 green:(arc4random()%256)/256.0 blue:(arc4random()%256)/256.0 alpha:1.0];
                carouselConfig.pageTintColor = [UIColor colorWithRed:(arc4random()%256)/256.0 green:(arc4random()%256)/256.0 blue:(arc4random()%256)/256.0 alpha:1.0];
                return carouselConfig;
            } array:imageArray2 titleArray:titleArray2];
        }
    }
    
}

@end


================================================
FILE: JYCarousel/ViewController/CarouselTableViewCell.xib
================================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11134" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
    <dependencies>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11106"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <objects>
        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
        <tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" id="KGk-i7-Jjw" customClass="CarouselTableViewCell">
            <rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
            <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
            <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
                <frame key="frameInset" width="320" height="43"/>
                <autoresizingMask key="autoresizingMask"/>
            </tableViewCellContentView>
        </tableViewCell>
    </objects>
</document>


================================================
FILE: JYCarousel/ViewController/DemoViewController.h
================================================
//
//  DemoViewController.h
//  JYCarousel
//
//  Created by Dely on 16/11/30.
//  Copyright © 2016年 Dely. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface DemoViewController : UIViewController

@end


================================================
FILE: JYCarousel/ViewController/DemoViewController.m
================================================
//
//  DemoViewController.m
//  JYCarousel
//
//  Created by Dely on 16/11/30.
//  Copyright © 2016年 Dely. All rights reserved.
//

#import "DemoViewController.h"
#import "CarouselTableViewCell.h"
#import "JYCarousel.h"
#import "JYImageCache.h"

#define SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height
#define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width

@interface DemoViewController ()<UITableViewDataSource,UITableViewDelegate,JYCarouselDelegate>
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (nonatomic, strong) JYCarousel *carouselView1;
@property (nonatomic, strong) JYCarousel *carouselView2;

@end

@implementation DemoViewController




- (void)viewDidLoad {
    [super viewDidLoad];
    self.edgesForExtendedLayout = UIRectEdgeNone;
    
    [self addCarouselView1];
    [self addCarouselView2];
    
    [self.tableView registerNib:[UINib nibWithNibName:@"CarouselTableViewCell" bundle:nil] forCellReuseIdentifier:@"CarouselTableViewCell"];
    [self.tableView reloadData];
    
}

#pragma mark ======================block回调方式创建======================
- (void)addCarouselView1{
    
    //block方式创建
    __weak typeof(self) weakSelf = self;
    NSMutableArray *imageArray = [[NSMutableArray alloc] initWithArray: @[@"1.jpg",@"2.jpg",@"3.jpg",@"4.jpg"]];
    
    if (!_carouselView1) {
        _carouselView1= [[JYCarousel alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 100) configBlock:^JYConfiguration *(JYConfiguration *carouselConfig) {
            carouselConfig.pageContollType = RightPageControl;
            carouselConfig.interValTime = 3;
            return carouselConfig;
        } clickBlock:^(NSInteger index) {
            [weakSelf clickIndex:index];
        }];
        [self.view addSubview:_carouselView1];
    }
    //开始轮播
    [_carouselView1 startCarouselWithArray:imageArray];
    
}

- (void)clickIndex:(NSInteger)index{
    NSLog(@"你点击图片索引index = %ld\n下面我更新样式代码在下面",index);
    //清除缓存数据 可以在启动的时候清除一次上一次轮播缓存,根据自己需要
//    [[JYImageCache sharedImageCache] jy_clearDiskCaches];
    
    //更新样式
    NSMutableArray *imageArray = [[NSMutableArray alloc] initWithArray: @[@"4.jpg",@"3.jpg",@"2.jpg",@"1.jpg"]];
    [_carouselView1 startCarouselWithNewConfig:^JYConfiguration *(JYConfiguration *carouselConfig) {
        carouselConfig.interValTime = 1.0;
        carouselConfig.pageContollType = LabelPageControl;
        return carouselConfig;
    } array:imageArray];
 
}

#pragma mark ======================代理回调方式创建======================
- (void)addCarouselView2{
    
    NSMutableArray *imageArray2 = [[NSMutableArray alloc] initWithArray: @[@"http://p1.bqimg.com/524586/894925a41a745ba8.jpg",@"http://p1.bqimg.com/524586/edd59898ac21642f.jpg",@"http://p1.bqimg.com/524586/d277aa654cd60c3d.jpg",@"http://p1.bqimg.com/524586/a49b8d3e1b953f25.jpg",@"http://p1.bqimg.com/524586/972bff3b7a5fb7e1.jpg"]];
    
    NSMutableArray *titleArray2 = [[NSMutableArray alloc] initWithArray: @[@"http://p1.bqimg.com/524586/894925a41a745ba8.jpg",@"http://p1.bqimg.com/524586/edd59898ac21642f.jpg",@"http://p1.bqimg.com/524586/d277aa654cd60c3d.jpg",@"http://p1.bqimg.com/524586/a49b8d3e1b953f25.jpg",@"http://p1.bqimg.com/524586/972bff3b7a5fb7e1.jpg"]];
    
    if (!_carouselView2) {
        _carouselView2 = [[JYCarousel alloc] initWithFrame:CGRectMake(0, 120, SCREEN_WIDTH, 100) configBlock:^JYConfiguration *(JYConfiguration *carouselConfig) {
            carouselConfig.pageContollType = MiddlePageControl;
            carouselConfig.pageTintColor = [UIColor whiteColor];
            carouselConfig.currentPageTintColor = [UIColor redColor];
            carouselConfig.placeholder = [UIImage imageNamed:@"default"];
            carouselConfig.faileReloadTimes = 5;
            carouselConfig.textAlignment = NSTextAlignmentLeft;
            carouselConfig.pageContollType = LabelPageControl;
            return carouselConfig;
        } target:self];
        
        [self.view addSubview:_carouselView2];
    }
    //开始轮播
    [_carouselView2 startCarouselWithArray:imageArray2 titleArray:titleArray2];
    
}

- (void)carouselViewClick:(NSInteger)index{
    NSLog(@"代理方式你点击图片索引index = %ld",index);
}



#pragma mark ======================tableView上JYCarousel应用======================

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    return 50;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    
    CarouselTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"CarouselTableViewCell" forIndexPath:indexPath];
    [cell updateViewWithIndexPath:indexPath];
    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    return 100;
}



#pragma mark ======================VC的生命周期方法=====================
- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    NSLog(@"进入VC:%@", [[self class] description]);
}

- (void)dealloc{
    NSLog(@"退出VC--无循环引用-----");
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    
}


@end


================================================
FILE: JYCarousel/ViewController/DemoViewController.xib
================================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11201" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <objects>
        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="DemoViewController">
            <connections>
                <outlet property="tableView" destination="veb-tN-6WE" id="ei2-J1-SaP"/>
                <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
            </connections>
        </placeholder>
        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
        <view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
            <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
            <subviews>
                <tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" translatesAutoresizingMaskIntoConstraints="NO" id="veb-tN-6WE">
                    <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
                    <connections>
                        <outlet property="dataSource" destination="-1" id="ObK-dN-s0x"/>
                        <outlet property="delegate" destination="-1" id="jrH-Rj-OPB"/>
                    </connections>
                </tableView>
            </subviews>
            <constraints>
                <constraint firstItem="veb-tN-6WE" firstAttribute="leading" secondItem="i5M-Pr-FkT" secondAttribute="leading" id="FKB-Ea-Zra"/>
                <constraint firstAttribute="trailing" secondItem="veb-tN-6WE" secondAttribute="trailing" id="RzI-xn-e2W"/>
                <constraint firstItem="veb-tN-6WE" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" constant="250" id="cEP-xZ-Jli"/>
                <constraint firstAttribute="bottom" secondItem="veb-tN-6WE" secondAttribute="bottom" id="vVk-Mt-BMb"/>
            </constraints>
        </view>
    </objects>
</document>


================================================
FILE: JYCarousel/ViewController/RootViewController.h
================================================
//
//  RootViewController.h
//  JYCarousel
//
//  Created by Dely on 16/11/30.
//  Copyright © 2016年 Dely. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface RootViewController : UIViewController

@end


================================================
FILE: JYCarousel/ViewController/RootViewController.m
================================================
//
//  RootViewController.m
//  JYCarousel
//
//  Created by Dely on 16/11/30.
//  Copyright © 2016年 Dely. All rights reserved.
//

#import "RootViewController.h"
#import "DemoViewController.h"

@interface RootViewController ()

@end

@implementation RootViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"JYCarousel";
}

- (IBAction)LookDemoAction:(UIButton *)sender {
    DemoViewController *DVC = [[DemoViewController alloc] init];
    [self.navigationController pushViewController:DVC animated:YES];
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    NSLog(@"memoryWarning");
}

@end


================================================
FILE: JYCarousel/ViewController/RootViewController.xib
================================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11201" systemVersion="15G31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11161"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <objects>
        <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="RootViewController">
            <connections>
                <outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
            </connections>
        </placeholder>
        <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
        <view clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="i5M-Pr-FkT">
            <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
            <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
            <subviews>
                <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="P4y-i5-1ip">
                    <constraints>
                        <constraint firstAttribute="width" constant="100" id="Ddl-Yf-yyZ"/>
                        <constraint firstAttribute="height" constant="30" id="rGi-Ms-eLj"/>
                    </constraints>
                    <state key="normal" title="Demo"/>
                    <connections>
                        <action selector="LookDemoAction:" destination="-1" eventType="touchUpInside" id="nTm-6c-0aa"/>
                    </connections>
                </button>
            </subviews>
            <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
            <constraints>
                <constraint firstItem="P4y-i5-1ip" firstAttribute="centerX" secondItem="i5M-Pr-FkT" secondAttribute="centerX" id="3Y2-FR-3mu"/>
                <constraint firstItem="P4y-i5-1ip" firstAttribute="top" secondItem="i5M-Pr-FkT" secondAttribute="top" constant="200" id="imA-nG-6VQ"/>
            </constraints>
        </view>
    </objects>
</document>


================================================
FILE: JYCarousel/main.m
================================================
//
//  main.m
//  JYCarousel
//
//  Created by Dely on 16/11/14.
//  Copyright © 2016年 Dely. All rights reserved.
//

#import <UIKit/UIKit.h>
#import "AppDelegate.h"

int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}


================================================
FILE: JYCarousel.podspec
================================================


Pod::Spec.new do |s|

  s.name         = "JYCarousel"
  s.version      = "0.0.3"
  s.summary      = "Simple carousel Library"
  s.homepage     = "https://github.com/Delyer/JYCarousel.git"

  s.license      = { :type => 'Apache License, Version 2.0', :text => <<-LICENSE
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
    LICENSE
  }

  s.author             = { "Delyer" => "jiayaoit@126.com" }
  s.platform     = :ios, "7.0"
  s.source       = { :git => "https://github.com/Delyer/JYCarousel.git", :tag => s.version }
  s.source_files  = "JYCarousel/JYCarousel/*.{h,m}"
  s.framework  = "UIKit", "Foundation"

end


================================================
FILE: JYCarousel.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
	archiveVersion = 1;
	classes = {
	};
	objectVersion = 46;
	objects = {

/* Begin PBXBuildFile section */
		A30184181DDEAD4000AC8F13 /* JYWeakTimer.m in Sources */ = {isa = PBXBuildFile; fileRef = A30184171DDEAD4000AC8F13 /* JYWeakTimer.m */; };
		A329E9581DDFED81003D312B /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = A329E9571DDFED81003D312B /* AppDelegate.m */; };
		A33B0F7F1DDA887400D85447 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = A33B0F7E1DDA887400D85447 /* main.m */; };
		A33B0F8A1DDA887400D85447 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = A33B0F891DDA887400D85447 /* Assets.xcassets */; };
		A33B0F8D1DDA887400D85447 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = A33B0F8B1DDA887400D85447 /* LaunchScreen.storyboard */; };
		A33B0FBA1DDA8BFF00D85447 /* JYConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = A33B0FB91DDA8BFF00D85447 /* JYConfiguration.m */; };
		A33B0FBD1DDA904000D85447 /* JYCarousel.m in Sources */ = {isa = PBXBuildFile; fileRef = A33B0FBC1DDA904000D85447 /* JYCarousel.m */; };
		A343A4C61DDD04540008192B /* JYPageControl.m in Sources */ = {isa = PBXBuildFile; fileRef = A343A4C51DDD04540008192B /* JYPageControl.m */; };
		A34E807C1EF0A07100ED6EA2 /* JYTitleLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = A34E807B1EF0A07100ED6EA2 /* JYTitleLabel.m */; };
		A355549C1DDE2C6600418BE6 /* JYImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = A355549B1DDE2C6600418BE6 /* JYImageDownloader.m */; };
		A355549F1DDE336B00418BE6 /* UIImageView+JYImageViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = A355549E1DDE336B00418BE6 /* UIImageView+JYImageViewManager.m */; };
		A35554A21DDE338C00418BE6 /* JYImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = A35554A11DDE338C00418BE6 /* JYImageCache.m */; };
		A373ED8D1DEF687E0006F533 /* RootViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A373ED8B1DEF687E0006F533 /* RootViewController.m */; };
		A373ED8E1DEF687E0006F533 /* RootViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = A373ED8C1DEF687E0006F533 /* RootViewController.xib */; };
		A373ED921DEF69B80006F533 /* DemoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A373ED901DEF69B80006F533 /* DemoViewController.m */; };
		A373ED931DEF69B80006F533 /* DemoViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = A373ED911DEF69B80006F533 /* DemoViewController.xib */; };
		A3ABF4C31DEF589C0002A01D /* CarouselTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = A3ABF4C11DEF589C0002A01D /* CarouselTableViewCell.m */; };
		A3ABF4C41DEF589C0002A01D /* CarouselTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = A3ABF4C21DEF589C0002A01D /* CarouselTableViewCell.xib */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
		A30184161DDEAD4000AC8F13 /* JYWeakTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JYWeakTimer.h; sourceTree = "<group>"; };
		A30184171DDEAD4000AC8F13 /* JYWeakTimer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JYWeakTimer.m; sourceTree = "<group>"; };
		A329E9561DDFED81003D312B /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
		A329E9571DDFED81003D312B /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
		A33B0F7A1DDA887400D85447 /* JYCarousel.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JYCarousel.app; sourceTree = BUILT_PRODUCTS_DIR; };
		A33B0F7E1DDA887400D85447 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
		A33B0F891DDA887400D85447 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
		A33B0F8C1DDA887400D85447 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
		A33B0F8E1DDA887400D85447 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
		A33B0FB81DDA8BFF00D85447 /* JYConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JYConfiguration.h; sourceTree = "<group>"; };
		A33B0FB91DDA8BFF00D85447 /* JYConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JYConfiguration.m; sourceTree = "<group>"; };
		A33B0FBB1DDA904000D85447 /* JYCarousel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JYCarousel.h; sourceTree = "<group>"; };
		A33B0FBC1DDA904000D85447 /* JYCarousel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JYCarousel.m; sourceTree = "<group>"; };
		A343A4C41DDD04540008192B /* JYPageControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JYPageControl.h; sourceTree = "<group>"; };
		A343A4C51DDD04540008192B /* JYPageControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JYPageControl.m; sourceTree = "<group>"; };
		A34E807A1EF0A07100ED6EA2 /* JYTitleLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JYTitleLabel.h; sourceTree = "<group>"; };
		A34E807B1EF0A07100ED6EA2 /* JYTitleLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JYTitleLabel.m; sourceTree = "<group>"; };
		A355549A1DDE2C6600418BE6 /* JYImageDownloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JYImageDownloader.h; sourceTree = "<group>"; };
		A355549B1DDE2C6600418BE6 /* JYImageDownloader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JYImageDownloader.m; sourceTree = "<group>"; };
		A355549D1DDE336B00418BE6 /* UIImageView+JYImageViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImageView+JYImageViewManager.h"; sourceTree = "<group>"; };
		A355549E1DDE336B00418BE6 /* UIImageView+JYImageViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImageView+JYImageViewManager.m"; sourceTree = "<group>"; };
		A35554A01DDE338C00418BE6 /* JYImageCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JYImageCache.h; sourceTree = "<group>"; };
		A35554A11DDE338C00418BE6 /* JYImageCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JYImageCache.m; sourceTree = "<group>"; };
		A373ED8A1DEF687E0006F533 /* RootViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RootViewController.h; sourceTree = "<group>"; };
		A373ED8B1DEF687E0006F533 /* RootViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RootViewController.m; sourceTree = "<group>"; };
		A373ED8C1DEF687E0006F533 /* RootViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RootViewController.xib; sourceTree = "<group>"; };
		A373ED8F1DEF69B80006F533 /* DemoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DemoViewController.h; sourceTree = "<group>"; };
		A373ED901DEF69B80006F533 /* DemoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DemoViewController.m; sourceTree = "<group>"; };
		A373ED911DEF69B80006F533 /* DemoViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = DemoViewController.xib; sourceTree = "<group>"; };
		A3ABF4C01DEF589C0002A01D /* CarouselTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CarouselTableViewCell.h; sourceTree = "<group>"; };
		A3ABF4C11DEF589C0002A01D /* CarouselTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CarouselTableViewCell.m; sourceTree = "<group>"; };
		A3ABF4C21DEF589C0002A01D /* CarouselTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CarouselTableViewCell.xib; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
		A33B0F771DDA887400D85447 /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
		A329E9551DDFED81003D312B /* App */ = {
			isa = PBXGroup;
			children = (
				A329E9561DDFED81003D312B /* AppDelegate.h */,
				A329E9571DDFED81003D312B /* AppDelegate.m */,
			);
			path = App;
			sourceTree = "<group>";
		};
		A33B0F711DDA887400D85447 = {
			isa = PBXGroup;
			children = (
				A33B0F7C1DDA887400D85447 /* JYCarousel */,
				A33B0F7B1DDA887400D85447 /* Products */,
			);
			sourceTree = "<group>";
		};
		A33B0F7B1DDA887400D85447 /* Products */ = {
			isa = PBXGroup;
			children = (
				A33B0F7A1DDA887400D85447 /* JYCarousel.app */,
			);
			name = Products;
			sourceTree = "<group>";
		};
		A33B0F7C1DDA887400D85447 /* JYCarousel */ = {
			isa = PBXGroup;
			children = (
				A33B0FB31DDA8A2000D85447 /* JYCarousel */,
				A3ABF4B51DEF576D0002A01D /* ViewController */,
				A329E9551DDFED81003D312B /* App */,
				A33B0FB71DDA8A5A00D85447 /* Resoure(资源) */,
				A33B0F7D1DDA887400D85447 /* Supporting Files */,
			);
			path = JYCarousel;
			sourceTree = "<group>";
		};
		A33B0F7D1DDA887400D85447 /* Supporting Files */ = {
			isa = PBXGroup;
			children = (
				A33B0F7E1DDA887400D85447 /* main.m */,
			);
			name = "Supporting Files";
			sourceTree = "<group>";
		};
		A33B0FB31DDA8A2000D85447 /* JYCarousel */ = {
			isa = PBXGroup;
			children = (
				A33B0FBB1DDA904000D85447 /* JYCarousel.h */,
				A33B0FBC1DDA904000D85447 /* JYCarousel.m */,
				A33B0FB81DDA8BFF00D85447 /* JYConfiguration.h */,
				A33B0FB91DDA8BFF00D85447 /* JYConfiguration.m */,
				A343A4C41DDD04540008192B /* JYPageControl.h */,
				A343A4C51DDD04540008192B /* JYPageControl.m */,
				A34E807A1EF0A07100ED6EA2 /* JYTitleLabel.h */,
				A34E807B1EF0A07100ED6EA2 /* JYTitleLabel.m */,
				A355549D1DDE336B00418BE6 /* UIImageView+JYImageViewManager.h */,
				A355549E1DDE336B00418BE6 /* UIImageView+JYImageViewManager.m */,
				A355549A1DDE2C6600418BE6 /* JYImageDownloader.h */,
				A355549B1DDE2C6600418BE6 /* JYImageDownloader.m */,
				A35554A01DDE338C00418BE6 /* JYImageCache.h */,
				A35554A11DDE338C00418BE6 /* JYImageCache.m */,
				A30184161DDEAD4000AC8F13 /* JYWeakTimer.h */,
				A30184171DDEAD4000AC8F13 /* JYWeakTimer.m */,
			);
			path = JYCarousel;
			sourceTree = "<group>";
		};
		A33B0FB71DDA8A5A00D85447 /* Resoure(资源) */ = {
			isa = PBXGroup;
			children = (
				A33B0F8E1DDA887400D85447 /* Info.plist */,
				A33B0F891DDA887400D85447 /* Assets.xcassets */,
				A33B0F8B1DDA887400D85447 /* LaunchScreen.storyboard */,
			);
			name = "Resoure(资源)";
			sourceTree = "<group>";
		};
		A3ABF4B51DEF576D0002A01D /* ViewController */ = {
			isa = PBXGroup;
			children = (
				A373ED8A1DEF687E0006F533 /* RootViewController.h */,
				A373ED8B1DEF687E0006F533 /* RootViewController.m */,
				A373ED8C1DEF687E0006F533 /* RootViewController.xib */,
				A373ED8F1DEF69B80006F533 /* DemoViewController.h */,
				A373ED901DEF69B80006F533 /* DemoViewController.m */,
				A373ED911DEF69B80006F533 /* DemoViewController.xib */,
				A3ABF4C01DEF589C0002A01D /* CarouselTableViewCell.h */,
				A3ABF4C11DEF589C0002A01D /* CarouselTableViewCell.m */,
				A3ABF4C21DEF589C0002A01D /* CarouselTableViewCell.xib */,
			);
			path = ViewController;
			sourceTree = "<group>";
		};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
		A33B0F791DDA887400D85447 /* JYCarousel */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = A33B0FA71DDA887400D85447 /* Build configuration list for PBXNativeTarget "JYCarousel" */;
			buildPhases = (
				A33B0F761DDA887400D85447 /* Sources */,
				A33B0F771DDA887400D85447 /* Frameworks */,
				A33B0F781DDA887400D85447 /* Resources */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = JYCarousel;
			productName = JYCarousel;
			productReference = A33B0F7A1DDA887400D85447 /* JYCarousel.app */;
			productType = "com.apple.product-type.application";
		};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
		A33B0F721DDA887400D85447 /* Project object */ = {
			isa = PBXProject;
			attributes = {
				LastUpgradeCheck = 0800;
				ORGANIZATIONNAME = Dely;
				TargetAttributes = {
					A33B0F791DDA887400D85447 = {
						CreatedOnToolsVersion = 8.0;
						ProvisioningStyle = Manual;
					};
				};
			};
			buildConfigurationList = A33B0F751DDA887400D85447 /* Build configuration list for PBXProject "JYCarousel" */;
			compatibilityVersion = "Xcode 3.2";
			developmentRegion = English;
			hasScannedForEncodings = 0;
			knownRegions = (
				en,
				Base,
			);
			mainGroup = A33B0F711DDA887400D85447;
			productRefGroup = A33B0F7B1DDA887400D85447 /* Products */;
			projectDirPath = "";
			projectRoot = "";
			targets = (
				A33B0F791DDA887400D85447 /* JYCarousel */,
			);
		};
/* End PBXProject section */

/* Begin PBXResourcesBuildPhase section */
		A33B0F781DDA887400D85447 /* Resources */ = {
			isa = PBXResourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				A33B0F8D1DDA887400D85447 /* LaunchScreen.storyboard in Resources */,
				A3ABF4C41DEF589C0002A01D /* CarouselTableViewCell.xib in Resources */,
				A373ED8E1DEF687E0006F533 /* RootViewController.xib in Resources */,
				A33B0F8A1DDA887400D85447 /* Assets.xcassets in Resources */,
				A373ED931DEF69B80006F533 /* DemoViewController.xib in Resources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXResourcesBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
		A33B0F761DDA887400D85447 /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				A33B0F7F1DDA887400D85447 /* main.m in Sources */,
				A373ED8D1DEF687E0006F533 /* RootViewController.m in Sources */,
				A355549C1DDE2C6600418BE6 /* JYImageDownloader.m in Sources */,
				A373ED921DEF69B80006F533 /* DemoViewController.m in Sources */,
				A30184181DDEAD4000AC8F13 /* JYWeakTimer.m in Sources */,
				A33B0FBD1DDA904000D85447 /* JYCarousel.m in Sources */,
				A3ABF4C31DEF589C0002A01D /* CarouselTableViewCell.m in Sources */,
				A355549F1DDE336B00418BE6 /* UIImageView+JYImageViewManager.m in Sources */,
				A329E9581DDFED81003D312B /* AppDelegate.m in Sources */,
				A34E807C1EF0A07100ED6EA2 /* JYTitleLabel.m in Sources */,
				A343A4C61DDD04540008192B /* JYPageControl.m in Sources */,
				A35554A21DDE338C00418BE6 /* JYImageCache.m in Sources */,
				A33B0FBA1DDA8BFF00D85447 /* JYConfiguration.m in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXSourcesBuildPhase section */

/* Begin PBXVariantGroup section */
		A33B0F8B1DDA887400D85447 /* LaunchScreen.storyboard */ = {
			isa = PBXVariantGroup;
			children = (
				A33B0F8C1DDA887400D85447 /* Base */,
			);
			name = LaunchScreen.storyboard;
			sourceTree = "<group>";
		};
/* End PBXVariantGroup section */

/* Begin XCBuildConfiguration section */
		A33B0FA51DDA887400D85447 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ALWAYS_SEARCH_USER_PATHS = NO;
				CLANG_ANALYZER_NONNULL = YES;
				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
				CLANG_CXX_LIBRARY = "libc++";
				CLANG_ENABLE_MODULES = YES;
				CLANG_ENABLE_OBJC_ARC = YES;
				CLANG_WARN_BOOL_CONVERSION = YES;
				CLANG_WARN_CONSTANT_CONVERSION = YES;
				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
				CLANG_WARN_EMPTY_BODY = YES;
				CLANG_WARN_ENUM_CONVERSION = YES;
				CLANG_WARN_INFINITE_RECURSION = YES;
				CLANG_WARN_INT_CONVERSION = YES;
				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
				CLANG_WARN_SUSPICIOUS_MOVES = YES;
				CLANG_WARN_UNREACHABLE_CODE = YES;
				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
				COPY_PHASE_STRIP = NO;
				DEBUG_INFORMATION_FORMAT = dwarf;
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				ENABLE_TESTABILITY = YES;
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_NO_COMMON_BLOCKS = YES;
				GCC_OPTIMIZATION_LEVEL = 0;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"DEBUG=1",
					"$(inherited)",
				);
				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
				GCC_WARN_UNDECLARED_SELECTOR = YES;
				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
				GCC_WARN_UNUSED_FUNCTION = YES;
				GCC_WARN_UNUSED_VARIABLE = YES;
				IPHONEOS_DEPLOYMENT_TARGET = 10.0;
				MTL_ENABLE_DEBUG_INFO = YES;
				ONLY_ACTIVE_ARCH = YES;
				SDKROOT = iphoneos;
				TARGETED_DEVICE_FAMILY = "1,2";
			};
			name = Debug;
		};
		A33B0FA61DDA887400D85447 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ALWAYS_SEARCH_USER_PATHS = NO;
				CLANG_ANALYZER_NONNULL = YES;
				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
				CLANG_CXX_LIBRARY = "libc++";
				CLANG_ENABLE_MODULES = YES;
				CLANG_ENABLE_OBJC_ARC = YES;
				CLANG_WARN_BOOL_CONVERSION = YES;
				CLANG_WARN_CONSTANT_CONVERSION = YES;
				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
				CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
				CLANG_WARN_EMPTY_BODY = YES;
				CLANG_WARN_ENUM_CONVERSION = YES;
				CLANG_WARN_INFINITE_RECURSION = YES;
				CLANG_WARN_INT_CONVERSION = YES;
				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
				CLANG_WARN_SUSPICIOUS_MOVES = YES;
				CLANG_WARN_UNREACHABLE_CODE = YES;
				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
				COPY_PHASE_STRIP = NO;
				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
				ENABLE_NS_ASSERTIONS = NO;
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_NO_COMMON_BLOCKS = YES;
				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
				GCC_WARN_UNDECLARED_SELECTOR = YES;
				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
				GCC_WARN_UNUSED_FUNCTION = YES;
				GCC_WARN_UNUSED_VARIABLE = YES;
				IPHONEOS_DEPLOYMENT_TARGET = 10.0;
				MTL_ENABLE_DEBUG_INFO = NO;
				SDKROOT = iphoneos;
				TARGETED_DEVICE_FAMILY = "1,2";
				VALIDATE_PRODUCT = YES;
			};
			name = Release;
		};
		A33B0FA81DDA887400D85447 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
				DEVELOPMENT_TEAM = "";
				INFOPLIST_FILE = JYCarousel/Info.plist;
				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
				PRODUCT_BUNDLE_IDENTIFIER = Dely.JYCarousel;
				PRODUCT_NAME = "$(TARGET_NAME)";
			};
			name = Debug;
		};
		A33B0FA91DDA887400D85447 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
				DEVELOPMENT_TEAM = "";
				INFOPLIST_FILE = JYCarousel/Info.plist;
				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
				PRODUCT_BUNDLE_IDENTIFIER = Dely.JYCarousel;
				PRODUCT_NAME = "$(TARGET_NAME)";
			};
			name = Release;
		};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
		A33B0F751DDA887400D85447 /* Build configuration list for PBXProject "JYCarousel" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				A33B0FA51DDA887400D85447 /* Debug */,
				A33B0FA61DDA887400D85447 /* Release */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
		A33B0FA71DDA887400D85447 /* Build configuration list for PBXNativeTarget "JYCarousel" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				A33B0FA81DDA887400D85447 /* Debug */,
				A33B0FA91DDA887400D85447 /* Release */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
/* End XCConfigurationList section */
	};
	rootObject = A33B0F721DDA887400D85447 /* Project object */;
}


================================================
FILE: JYCarousel.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
   version = "1.0">
   <FileRef
      location = "self:JYCarousel.xcodeproj">
   </FileRef>
</Workspace>


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2016 Delyer <jiayaoit@126.com>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.



================================================
FILE: README.md
================================================
# **轮播组件:JYCarousel**

**开源库名称:** **JYCarousel**

**开源库当前版本:** **0.0.3**

**开源库简介:** 这是一个使用起来非常简单的开源轮播库,自带下载和缓存,不会造成循环引用,不用考虑定时器不会销毁(我都已经帮你做好了)。


![](https://github.com/Delyer/JYCarousel/raw/master/JYCarouselImage/JYCarouselIcon.png)

## **1. 轮播库引用方式**

- **1.直接下载工程,把包含源代码的文件夹JYCarousel引入工程即可使用**
- **2.支持cocoapods。当前版本0.0.2 在Podfile文件中添加以下文字即可:**
```
pod 'JYCarousel', '~> 0.0.3'
```

## **2. 轮播基本原理**

使用三个imageView添加到ScrollView,始终保持中间的imageView在可视界面里。当前的imageView滚动到下一个imageView,然后把下一个imageView滚动到三个imageView的中心位置,在这过程中赋值的时候是三个imageView同时赋值,滚动的时候找到最中间的imageView,把这个imageView的tag值设置为当前的索引,滚动完成后把这个imageView设置为中心滚动位置。

比如三张图A、B、C。要做的scrollview实际上应该是五张的大小顺序是C、A、B、C、A。初始偏移量设置到第二张,监听scrollview滑动事件。判断偏移量。当偏移量在第一张时将偏移量修改到第四张,当偏移量在第五张时将偏移量调整到第二章。这样在循环时比较流畅,才能无缝无限循环滚动


![](https://github.com/Delyer/JYCarousel/raw/master/JYCarouselImage/JYCarouselDemo.gif)


## **3. 轮播的特性**
- **无缝循环轮播,处理的很好,不会显得生硬**

- **自带图片下载和缓存,不依赖任何第三方,引入即可使用,不用任何配置**

- **支持block方式和delegate方式,使用起来巨方便**

- **随时根据需要清除缓存**

- **采用disk缓存,不会占用app内存,释放你的app内存**

- **可以随时更新轮播数据,完美切换,**

- **用户可自定义的属性多,具体见配置文件JYConfiguration**


## **4. 代码文件结构和功能**

**JYCarousel**

- **JYCarousel**
	- 作用:轮播组件的创建和开始
- **JYConfiguration** 
	- 作用:轮播组件的自定义配置,配置你想要的效果
- **JYPageControl** 
	- 作用:轮播组件的指示器样式
- **JYTitleLabel** 
	- 作用:标签的样式
- **JYWeakTimer**
	- 作用:轮播组件的弱引用定时器,解决NSTimer不能销毁的问题
- **UIImageView+JYImageViewManager** 
	- 作用:imageView请求网络图片的分类
- **JYImageDownloader**
	-  作用:请求网络图片
- **JYImageCache**
	- 作用:网络图片的缓存

![](https://github.com/Delyer/JYCarousel/raw/master/JYCarouselImage/JYCarouselStruct.png)

## **5. 轮播组件的使用**

#### **提供两个初始化方法:**

```
/**
 block方式回调初始化
 @param frame       frame
 @param configBlock 轮播属性配置
 @param clickBlock  点击回调
 @return carousel
 */
- (instancetype)initWithFrame:(CGRect)frame
                  configBlock:(CarouselConfigurationBlock)configBlock
                   clickBlock:(CarouselClickBlock)clickBlock;


/**
 delegate方式回调初始化
 @param frame       frame
 @param configBlock 轮播属性配置
 @param target      delegate
 @return carousel
 */
- (instancetype)initWithFrame:(CGRect)frame
                  configBlock:(CarouselConfigurationBlock)configBlock
                       target:(id<JYCarouselDelegate>)target;
```



#### **使用举例:**

##### **1.block回调方式创建:**

```
- (void)addCarouselView1{
    
    //block方式创建
    __weak typeof(self) weakSelf = self;
    NSMutableArray *imageArray = [[NSMutableArray alloc] initWithArray: @[@"1.jpg",@"2.jpg",@"3.jpg",@"4.jpg"]];
    
    if (!_carouselView1) {
        _carouselView1= [[JYCarousel alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 100) configBlock:^JYConfiguration *(JYConfiguration *carouselConfig) {
            carouselConfig.pageContollType = RightPageControl;
            carouselConfig.interValTime = 3;
            return carouselConfig;
        } clickBlock:^(NSInteger index) {
            [weakSelf clickIndex:index];
        }];
        [self.view addSubview:_carouselView1];
    }
    //开始轮播
    [_carouselView1 startCarouselWithArray:imageArray];
    
}

```

##### **2.delegate回调方式创建:**

```
//遵循协议
@interface SubViewController ()<JYCarouselDelegate>

//创建
- (void)addCarouselView2{
    
    NSMutableArray *imageArray2 = [[NSMutableArray alloc] initWithArray: @[@"http://p1.bqimg.com/524586/894925a41a745ba8.jpg",@"http://p1.bqimg.com/524586/edd59898ac21642f.jpg",@"http://p1.bqimg.com/524586/d277aa654cd60c3d.jpg",@"http://p1.bqimg.com/524586/a49b8d3e1b953f25.jpg",@"http://p1.bqimg.com/524586/972bff3b7a5fb7e1.jpg"]];
    
    NSMutableArray *titleArray2 = [[NSMutableArray alloc] initWithArray: @[@"http://p1.bqimg.com/524586/894925a41a745ba8.jpg",@"http://p1.bqimg.com/524586/edd59898ac21642f.jpg",@"http://p1.bqimg.com/524586/d277aa654cd60c3d.jpg",@"http://p1.bqimg.com/524586/a49b8d3e1b953f25.jpg",@"http://p1.bqimg.com/524586/972bff3b7a5fb7e1.jpg"]];
    
    if (!_carouselView2) {
        _carouselView2 = [[JYCarousel alloc] initWithFrame:CGRectMake(0, 120, SCREEN_WIDTH, 100) configBlock:^JYConfiguration *(JYConfiguration *carouselConfig) {
            carouselConfig.pageContollType = MiddlePageControl;
            carouselConfig.pageTintColor = [UIColor whiteColor];
            carouselConfig.currentPageTintColor = [UIColor redColor];
            carouselConfig.placeholder = [UIImage imageNamed:@"default"];
            carouselConfig.faileReloadTimes = 5;
            carouselConfig.textAlignment = NSTextAlignmentLeft;
            carouselConfig.pageContollType = LabelPageControl;
            return carouselConfig;
        } target:self];
        
        [self.view addSubview:_carouselView2];
    }
    //开始轮播
    [_carouselView2 startCarouselWithArray:imageArray2 titleArray:titleArray2];
    
}

//回调方法
- (void)carouselViewClick:(NSInteger)index{
    NSLog(@"代理方式你点击图片索引index = %ld",index);
    //清楚缓存数据 可以在app启动的时候清楚上一次轮播缓存,根据自己需要
    [[JYImageCache sharedImageCache] jy_clearDiskCaches];
}

```

## **6. 缓存机制**
- 启动时可设置超时自动清除缓存功能

```
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
	//添加以下方法即可
    //每次启动时,检查是否超时,清除缓存(单位是小时这里是10分钟)
    [[JYImageCache sharedImageCache] jy_clearDiskCachesWithTimeout:10.0/60];
}
```

- 手动清除缓存

```
//清除缓存数据 根据自己需要调用
[[JYImageCache sharedImageCache] jy_clearDiskCaches];
```


## **7. 注意事项**

内存得不到释放造成内存泄露,使用循环引用了。请注意使用。看下面在block回调处,对Self是使用弱引用的,不然内存是得不到释放的。
<pre>
// 请使用weakSelf,不然内存得不到释放
  __weak typeof(self) weakSelf = self;
  //图片数组(或者图片URL,图片URL字符串,图片UIImage对象)
  NSMutableArray *imageArray = [[NSMutableArray alloc] initWithArray: @[@1.jpg,@2.jpg,@3.jpg,@4.jpg]];
  JYCarousel *carouselView = [[JYCarousel alloc] initWithFrame:CGRectMake(0, 64, ViewWidth(self.view), 100) configBlock:nil clickBlock:NSInteger index {
    //点击imageView回调方法
    [weakSelf clickIndex:index];
  }];
  //开始轮播
 [carouselView startCarouselWithArray:imageArray];
 [self.view addSubview:carouselView];
</pre>


## **8. 版本更新日志**

- 添加启动超时自动清除缓存功能
- 添加titlLabel标签
- 去除切换动画

## **喜欢就给个Star吧!**
Download .txt
gitextract_i9tucx6a/

├── .gitignore
├── JYCarousel/
│   ├── App/
│   │   ├── AppDelegate.h
│   │   └── AppDelegate.m
│   ├── Assets.xcassets/
│   │   ├── AppIcon.appiconset/
│   │   │   └── Contents.json
│   │   ├── Contents.json
│   │   ├── default.imageset/
│   │   │   └── Contents.json
│   │   └── images/
│   │       ├── 1.imageset/
│   │       │   └── Contents.json
│   │       ├── 2.imageset/
│   │       │   └── Contents.json
│   │       ├── 3.imageset/
│   │       │   └── Contents.json
│   │       ├── 4.imageset/
│   │       │   └── Contents.json
│   │       ├── 5.imageset/
│   │       │   └── Contents.json
│   │       └── Contents.json
│   ├── Base.lproj/
│   │   └── LaunchScreen.storyboard
│   ├── Info.plist
│   ├── JYCarousel/
│   │   ├── JYCarousel.h
│   │   ├── JYCarousel.m
│   │   ├── JYConfiguration.h
│   │   ├── JYConfiguration.m
│   │   ├── JYImageCache.h
│   │   ├── JYImageCache.m
│   │   ├── JYImageDownloader.h
│   │   ├── JYImageDownloader.m
│   │   ├── JYPageControl.h
│   │   ├── JYPageControl.m
│   │   ├── JYTitleLabel.h
│   │   ├── JYTitleLabel.m
│   │   ├── JYWeakTimer.h
│   │   ├── JYWeakTimer.m
│   │   ├── UIImageView+JYImageViewManager.h
│   │   └── UIImageView+JYImageViewManager.m
│   ├── ViewController/
│   │   ├── CarouselTableViewCell.h
│   │   ├── CarouselTableViewCell.m
│   │   ├── CarouselTableViewCell.xib
│   │   ├── DemoViewController.h
│   │   ├── DemoViewController.m
│   │   ├── DemoViewController.xib
│   │   ├── RootViewController.h
│   │   ├── RootViewController.m
│   │   └── RootViewController.xib
│   └── main.m
├── JYCarousel.podspec
├── JYCarousel.xcodeproj/
│   ├── project.pbxproj
│   └── project.xcworkspace/
│       └── contents.xcworkspacedata
├── LICENSE
└── README.md
Download .txt
SYMBOL INDEX (1 symbols across 1 files)

FILE: JYCarousel/JYCarousel/JYConfiguration.h
  type JYConfiguration (line 40) | typedef JYConfiguration *(^CarouselConfigurationBlock)(JYConfiguration *...
Condensed preview — 45 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (117K chars).
[
  {
    "path": ".gitignore",
    "chars": 1298,
    "preview": "# Xcode\n#\n# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore\n\n"
  },
  {
    "path": "JYCarousel/App/AppDelegate.h",
    "chars": 268,
    "preview": "//\n//  AppDelegate.h\n//  JYCarousel\n//\n//  Created by Dely on 16/11/14.\n//  Copyright © 2016年 Dely. All rights reserved."
  },
  {
    "path": "JYCarousel/App/AppDelegate.m",
    "chars": 2535,
    "preview": "//\n//  AppDelegate.m\n//  JYCarousel\n//\n//  Created by Dely on 16/11/14.\n//  Copyright © 2016年 Dely. All rights reserved."
  },
  {
    "path": "JYCarousel/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "chars": 1495,
    "preview": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"iphone\",\n      \"size\" : \"20x20\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\""
  },
  {
    "path": "JYCarousel/Assets.xcassets/Contents.json",
    "chars": 62,
    "preview": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "JYCarousel/Assets.xcassets/default.imageset/Contents.json",
    "chars": 307,
    "preview": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n     "
  },
  {
    "path": "JYCarousel/Assets.xcassets/images/1.imageset/Contents.json",
    "chars": 298,
    "preview": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"1.jpg\",\n      \"scale\" : \"1x\"\n    },\n    {\n      "
  },
  {
    "path": "JYCarousel/Assets.xcassets/images/2.imageset/Contents.json",
    "chars": 298,
    "preview": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"2.jpg\",\n      \"scale\" : \"1x\"\n    },\n    {\n      "
  },
  {
    "path": "JYCarousel/Assets.xcassets/images/3.imageset/Contents.json",
    "chars": 298,
    "preview": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"3.jpg\",\n      \"scale\" : \"1x\"\n    },\n    {\n      "
  },
  {
    "path": "JYCarousel/Assets.xcassets/images/4.imageset/Contents.json",
    "chars": 298,
    "preview": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"4.jpg\",\n      \"scale\" : \"1x\"\n    },\n    {\n      "
  },
  {
    "path": "JYCarousel/Assets.xcassets/images/5.imageset/Contents.json",
    "chars": 298,
    "preview": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"5.jpg\",\n      \"scale\" : \"1x\"\n    },\n    {\n      "
  },
  {
    "path": "JYCarousel/Assets.xcassets/images/Contents.json",
    "chars": 62,
    "preview": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "JYCarousel/Base.lproj/LaunchScreen.storyboard",
    "chars": 1740,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard"
  },
  {
    "path": "JYCarousel/Info.plist",
    "chars": 1545,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "JYCarousel/JYCarousel/JYCarousel.h",
    "chars": 2087,
    "preview": "//\n//  JYCarousel.h\n//  JYCarousel\n//\n//  Created by Dely on 16/11/14.\n//  Copyright © 2016年 Dely. All rights reserved.\n"
  },
  {
    "path": "JYCarousel/JYCarousel/JYCarousel.m",
    "chars": 13100,
    "preview": "//\n//  JYCarousel.m\n//  JYCarousel\n//\n//  Created by Dely on 16/11/14.\n//  Copyright © 2016年 Dely. All rights reserved.\n"
  },
  {
    "path": "JYCarousel/JYCarousel/JYConfiguration.h",
    "chars": 2443,
    "preview": "//\n//  JYConfiguration.h\n//  JYCarousel\n//\n//  Created by Dely on 16/11/14.\n//  Copyright © 2016年 Dely. All rights reser"
  },
  {
    "path": "JYCarousel/JYCarousel/JYConfiguration.m",
    "chars": 196,
    "preview": "//\n//  JYConfiguration.m\n//  JYCarousel\n//\n//  Created by Dely on 16/11/14.\n//  Copyright © 2016年 Dely. All rights reser"
  },
  {
    "path": "JYCarousel/JYCarousel/JYImageCache.h",
    "chars": 975,
    "preview": "//\n//  JYImageCache.h\n//  JYCarousel\n//\n//  Created by Dely on 16/11/17.\n//  Copyright © 2016年 Dely. All rights reserved"
  },
  {
    "path": "JYCarousel/JYCarousel/JYImageCache.m",
    "chars": 7296,
    "preview": "//\n//  JYImageCache.m\n//  JYCarousel\n//\n//  Created by Dely on 16/11/17.\n//  Copyright © 2016年 Dely. All rights reserved"
  },
  {
    "path": "JYCarousel/JYCarousel/JYImageDownloader.h",
    "chars": 759,
    "preview": "//\n//  JYImageDownloader.h\n//  JYCarousel\n//\n//  Created by Dely on 16/11/17.\n//  Copyright © 2016年 Dely. All rights res"
  },
  {
    "path": "JYCarousel/JYCarousel/JYImageDownloader.m",
    "chars": 3540,
    "preview": "//\n//  JYImageDownloader.m\n//  JYCarousel\n//\n//  Created by Dely on 16/11/17.\n//  Copyright © 2016年 Dely. All rights res"
  },
  {
    "path": "JYCarousel/JYCarousel/JYPageControl.h",
    "chars": 441,
    "preview": "//\n//  JYPageControl.h\n//  JYCarousel\n//\n//  Created by Dely on 16/11/16.\n//  Copyright © 2016年 Dely. All rights reserve"
  },
  {
    "path": "JYCarousel/JYCarousel/JYPageControl.m",
    "chars": 4268,
    "preview": "//\n//  JYPageControl.m\n//  JYCarousel\n//\n//  Created by Dely on 16/11/16.\n//  Copyright © 2016年 Dely. All rights reserve"
  },
  {
    "path": "JYCarousel/JYCarousel/JYTitleLabel.h",
    "chars": 408,
    "preview": "//\n//  JYTitleLabel.h\n//  JYCarousel\n//\n//  Created by Dely on 2017/6/13.\n//  Copyright © 2017年 Dely. All rights reserve"
  },
  {
    "path": "JYCarousel/JYCarousel/JYTitleLabel.m",
    "chars": 2505,
    "preview": "//\n//  JYTitleLabel.m\n//  JYCarousel\n//\n//  Created by Dely on 2017/6/13.\n//  Copyright © 2017年 Dely. All rights reserve"
  },
  {
    "path": "JYCarousel/JYCarousel/JYWeakTimer.h",
    "chars": 506,
    "preview": "//\n//  JYWeakTimer.h\n//  JYCarousel\n//\n//  Created by Dely on 16/11/17.\n//  Copyright © 2016年 Dely. All rights reserved."
  },
  {
    "path": "JYCarousel/JYCarousel/JYWeakTimer.m",
    "chars": 1627,
    "preview": "//\n//  JYWeakTimer.m\n//  JYCarousel\n//\n//  Created by Dely on 16/11/17.\n//  Copyright © 2016年 Dely. All rights reserved."
  },
  {
    "path": "JYCarousel/JYCarousel/UIImageView+JYImageViewManager.h",
    "chars": 983,
    "preview": "//\n//  UIImageView+JYImageViewManager.h\n//  JYCarousel\n//\n//  Created by Dely on 16/11/17.\n//  Copyright © 2016年 Dely. A"
  },
  {
    "path": "JYCarousel/JYCarousel/UIImageView+JYImageViewManager.m",
    "chars": 5468,
    "preview": "//\n//  UIImageView+JYImageViewManager.m\n//  JYCarousel\n//\n//  Created by Dely on 16/11/17.\n//  Copyright © 2016年 Dely. A"
  },
  {
    "path": "JYCarousel/ViewController/CarouselTableViewCell.h",
    "chars": 276,
    "preview": "//\n//  CarouselTableViewCell.h\n//  JYCarousel\n//\n//  Created by Dely on 16/11/30.\n//  Copyright © 2016年 Dely. All rights"
  },
  {
    "path": "JYCarousel/ViewController/CarouselTableViewCell.m",
    "chars": 3366,
    "preview": "//\n//  CarouselTableViewCell.m\n//  JYCarousel\n//\n//  Created by Dely on 16/11/30.\n//  Copyright © 2016年 Dely. All rights"
  },
  {
    "path": "JYCarousel/ViewController/CarouselTableViewCell.xib",
    "chars": 1435,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" versi"
  },
  {
    "path": "JYCarousel/ViewController/DemoViewController.h",
    "chars": 212,
    "preview": "//\n//  DemoViewController.h\n//  JYCarousel\n//\n//  Created by Dely on 16/11/30.\n//  Copyright © 2016年 Dely. All rights re"
  },
  {
    "path": "JYCarousel/ViewController/DemoViewController.m",
    "chars": 5215,
    "preview": "//\n//  DemoViewController.m\n//  JYCarousel\n//\n//  Created by Dely on 16/11/30.\n//  Copyright © 2016年 Dely. All rights re"
  },
  {
    "path": "JYCarousel/ViewController/DemoViewController.xib",
    "chars": 2620,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" versi"
  },
  {
    "path": "JYCarousel/ViewController/RootViewController.h",
    "chars": 212,
    "preview": "//\n//  RootViewController.h\n//  JYCarousel\n//\n//  Created by Dely on 16/11/30.\n//  Copyright © 2016年 Dely. All rights re"
  },
  {
    "path": "JYCarousel/ViewController/RootViewController.m",
    "chars": 647,
    "preview": "//\n//  RootViewController.m\n//  JYCarousel\n//\n//  Created by Dely on 16/11/30.\n//  Copyright © 2016年 Dely. All rights re"
  },
  {
    "path": "JYCarousel/ViewController/RootViewController.xib",
    "chars": 2549,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" versi"
  },
  {
    "path": "JYCarousel/main.m",
    "chars": 325,
    "preview": "//\n//  main.m\n//  JYCarousel\n//\n//  Created by Dely on 16/11/14.\n//  Copyright © 2016年 Dely. All rights reserved.\n//\n\n#i"
  },
  {
    "path": "JYCarousel.podspec",
    "chars": 1125,
    "preview": "\n\nPod::Spec.new do |s|\n\n  s.name         = \"JYCarousel\"\n  s.version      = \"0.0.3\"\n  s.summary      = \"Simple carousel L"
  },
  {
    "path": "JYCarousel.xcodeproj/project.pbxproj",
    "chars": 20815,
    "preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
  },
  {
    "path": "JYCarousel.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "chars": 155,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:JYCarousel.xcod"
  },
  {
    "path": "LICENSE",
    "chars": 1093,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2016 Delyer <jiayaoit@126.com>\n\nPermission is hereby granted, free of charge, to an"
  },
  {
    "path": "README.md",
    "chars": 5963,
    "preview": "# **轮播组件:JYCarousel**\n\n**开源库名称:** **JYCarousel**\n\n**开源库当前版本:** **0.0.3**\n\n**开源库简介:** 这是一个使用起来非常简单的开源轮播库,自带下载和缓存,不会造成循环引用"
  }
]

About this extraction

This page contains the full source code of the Delyer/JYCarousel GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 45 files (101.0 KB), approximately 30.3k tokens, and a symbol index with 1 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!