Full Code of yangKJ/KJBannerViewDemo for AI

master 1f98763f62bd cached
82 files
283.4 KB
78.1k tokens
8 symbols
1 requests
Download .txt
Showing preview only (316K chars total). Download the full file or copy to clipboard to get everything.
Repository: yangKJ/KJBannerViewDemo
Branch: master
Commit: 1f98763f62bd
Files: 82
Total size: 283.4 KB

Directory structure:
gitextract_0063ocvp/

├── .gitignore
├── CHANGELOG.md
├── KJBannerView.podspec
├── KJBannerViewDemo/
│   ├── AppDelegate.h
│   ├── AppDelegate.m
│   ├── Masonry/
│   │   ├── MASCompositeConstraint.h
│   │   ├── MASCompositeConstraint.m
│   │   ├── MASConstraint+Private.h
│   │   ├── MASConstraint.h
│   │   ├── MASConstraint.m
│   │   ├── MASConstraintMaker.h
│   │   ├── MASConstraintMaker.m
│   │   ├── MASLayoutConstraint.h
│   │   ├── MASLayoutConstraint.m
│   │   ├── MASUtilities.h
│   │   ├── MASViewAttribute.h
│   │   ├── MASViewAttribute.m
│   │   ├── MASViewConstraint.h
│   │   ├── MASViewConstraint.m
│   │   ├── Masonry.h
│   │   ├── NSArray+MASAdditions.h
│   │   ├── NSArray+MASAdditions.m
│   │   ├── NSArray+MASShorthandAdditions.h
│   │   ├── NSLayoutConstraint+MASDebugAdditions.h
│   │   ├── NSLayoutConstraint+MASDebugAdditions.m
│   │   ├── View+MASAdditions.h
│   │   ├── View+MASAdditions.m
│   │   ├── View+MASShorthandAdditions.h
│   │   ├── ViewController+MASAdditions.h
│   │   └── ViewController+MASAdditions.m
│   ├── Modules/
│   │   ├── Controller/
│   │   │   ├── DownloadViewController.h
│   │   │   ├── DownloadViewController.m
│   │   │   ├── ViewController.h
│   │   │   └── ViewController.m
│   │   ├── Model/
│   │   │   ├── KJBannerModel.h
│   │   │   └── KJBannerModel.m
│   │   ├── View/
│   │   │   ├── KJCollectionViewCell.h
│   │   │   └── KJCollectionViewCell.m
│   │   └── ViewModel/
│   │       ├── KJViewModel.h
│   │       └── KJViewModel.m
│   └── Supporting Files/
│       ├── Assets.xcassets/
│       │   ├── AppIcon.appiconset/
│       │   │   └── Contents.json
│       │   ├── Contents.json
│       │   ├── IMG_4931.imageset/
│       │   │   ├── Contents.json
│       │   │   ├── Contents.json~Add 2.0.3
│       │   │   ├── Contents.json~HEAD
│       │   │   ├── IMG_4931.jpg~Add 2.0.3
│       │   │   └── IMG_4931.jpg~HEAD
│       │   ├── IMG_Guitar_52.imageset/
│       │   │   └── Contents.json
│       │   ├── ax.imageset/
│       │   │   └── Contents.json
│       │   └── z_ds.imageset/
│       │       └── Contents.json
│       ├── Base.lproj/
│       │   ├── LaunchScreen.storyboard
│       │   └── Main.storyboard
│       ├── Info.plist
│       └── main.m
├── KJBannerViewDemo.xcodeproj/
│   ├── project.pbxproj
│   ├── project.xcworkspace/
│   │   ├── contents.xcworkspacedata
│   │   └── xcshareddata/
│   │       └── IDEWorkspaceChecks.plist
│   └── xcshareddata/
│       └── xcschemes/
│           └── KJBannerViewDemo.xcscheme
├── LICENSE
├── README.md
└── Sources/
    ├── KJBannerHeader.h
    ├── KJBannerView/
    │   ├── KJBannerView.h
    │   ├── KJBannerView.m
    │   ├── KJBannerViewCell.h
    │   ├── KJBannerViewCell.m
    │   ├── KJBannerViewFlowLayout.h
    │   ├── KJBannerViewFlowLayout.m
    │   ├── KJBannerViewTimer.h
    │   └── KJBannerViewTimer.m
    ├── PageControl/
    │   ├── KJPageControl.h
    │   └── KJPageControl.m
    └── WebImage/
        ├── KJAutoPurgingCache.h
        ├── KJAutoPurgingCache.m
        ├── KJImageCache.h
        ├── KJImageCache.m
        ├── KJNetworkManager.h
        ├── KJNetworkManager.m
        ├── KJWebImageDownloader.h
        ├── KJWebImageDownloader.m
        ├── KJWebImageHeader.h
        ├── UIView+KJWebImage.h
        └── UIView+KJWebImage.m

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

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

## User settings
xcuserdata/

## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
*.xcscmblueprint
*.xccheckout

## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
build/
DerivedData/
*.moved-aside
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3

## Obj-C/Swift specific
*.hmap

## App packaging
*.ipa
*.dSYM.zip
*.dSYM

# 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/
#
# Add this line if you want to avoid checking in source code from the Xcode workspace
# *.xcworkspace

# 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://docs.fastlane.tools/best-practices/source-control/#source-control

fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots/**/*.png
fastlane/test_output

# Code Injection
#
# After new code Injection tools there's a generated folder /iOSInjectionProject
# https://github.com/johnno1962/injectionforxcode

iOSInjectionProject/


================================================
FILE: CHANGELOG.md
================================================
# <a id="功能介绍"></a>功能介绍
KJBannerView 是一款轮播Banner,支持gif和url混播,自带图片下载和缓存    
1. 缩放无限自动循环滚动  √    
2. 支持四种方向滚动,从左往右、从右往左、从上往下、从下往上  √  
3. 自定义继承,定制不同样式,详情使用请见Demo  √  
4. 支持网络动态图和网络图片和本地图片混合轮播  √  
5. 支持在Storyboard和Xib中创建并配置其属性  √  
6. 提供多种分页控件PageControl显示  √  
7. 自带缓存加载,内部封装网图下载缓存工具  √  
8. 清理指定时间段以前的图片资源数据  √  

> 备注:快捷打开浏览器命令,command + shift + 鼠标左键

# 版本更新日志

### [版本3.0.1](https://github.com/yangKJ/KJBannerViewDemo/tree/3.0.1)
- 拆分bannerView分类方法至`KJBannerViewCell`
- 完善预加载模板,结构命名调整

### [版本3.0.0](https://github.com/yangKJ/KJBannerViewDemo/tree/3.0.0)
- 改版重构,采用协议类似`UITableView`的处理方式
- 删除废弃代码和类等
- 抽离异步计时器`KJBannerViewTimer`

### [版本2.1.7](https://github.com/yangKJ/KJBannerViewDemo/tree/2.1.7)
- 规范代码,删除计数器
- bannerScale 默认不裁剪

### [版本2.1.6](https://github.com/yangKJ/KJBannerViewDemo/tree/2.1.6)
- 解决一条数据点击不响应问题
- 优化一下,规范代码

### [版本2.1.3](https://github.com/yangKJ/KJBannerViewDemo/tree/2.1.3)
- 抽离网络加载部分,pod 'KJBannerView/Downloader'
- 新增网络加载部分预渲染图片处理 `bannerPreRendering`

### [版本2.1.2](https://github.com/yangKJ/KJBannerViewDemo/tree/2.1.2)
- 更高效的圆角切割,避免离屏渲染
- 更换计时器,替换为异步GCD计时器
- 新增定制特定方位圆角字段
- 修复字段重名情况

### [版本2.1.0](https://github.com/yangKJ/KJBannerViewDemo/tree/2.1.0)
- 更换动态图处理播放控件,移除数据源类型
- 修改为异步播放本地动态图
- 去除原先的 UIImageView+KJWebImage、UIButton+KJWebImage
- 合并网图加载分类 UIView+KJWebImage
- 新增 KJBannerTimingClearManager 清理指定时间段以前的图片资源数据

### [版本2.0.11](https://github.com/yangKJ/KJBannerViewDemo/tree/2.0.11)
- 简练代码逻辑,整理修改重复代码
- 新增 UIView+KJWebImage 显示View内容图片

### [版本2.0.10](https://github.com/yangKJ/KJBannerViewDemo/tree/2.0.10)
- 修改网图显示,新增 KJBannerWebImageHandle 关联
- 性能优化,完善逻辑处理

### [版本2.0.9](https://github.com/yangKJ/KJBannerViewDemo/tree/2.0.9)
- 移除不再使用数据,优化逻辑操作
- 新增 UIImageView+KJWebImage 图片显示处理

### [版本2.0.8](https://github.com/yangKJ/KJBannerViewDemo/tree/2.0.8)
- 解决偶尔出现 Thread 1: EXC_ARITHMETIC (code=EXC_I386_DIV, subcode=0x0)
- 修复首次加载不出现问题,优化性能

### [版本2.0.7](https://github.com/yangKJ/KJBannerViewDemo/tree/2.0.7)
- KJPageView 新增显示位置属性 displayType 和 距离边界间隙 space
- 完善自定义控件方式 itemClass

### [版本2.0.6](https://github.com/yangKJ/KJBannerViewDemo/tree/2.0.6)
- 属性 rollType 新增从上往下和从下往上两种滚动方向
- 新增属性 showPageControl 是否显示分页控件
- 适配Masonry布局,请调用方法 kj_useMasonry

### [版本2.0.5](https://github.com/yangKJ/KJBannerViewDemo/tree/2.0.5)
- KJPageView 优化修改选中

### [版本2.0.4](https://github.com/yangKJ/KJBannerViewDemo/tree/2.0.4)
- KJBannerViewLoadManager 新增是否开启异步字段 `useAsync`
- 新增 KJBannerViewCacheManager+KJBannerGIF 动态图缓存相关 

### [版本2.0.3](https://github.com/yangKJ/KJBannerViewDemo/tree/2.0.3)
- 新增本地动态图播放
- KJBannerView 新增是否需要动态图缓存字段 `openGIFCache`

### [版本2.0.1](https://github.com/yangKJ/KJBannerViewDemo/tree/2.0.1)
- 优化自带第一条数据不显示问题
- 优化卡顿问题
- KJBannerView 修改xib属性字段名

### [版本2.0.0](https://github.com/yangKJ/KJBannerViewDemo/tree/2.0.0)
- 重写网络请求板块,
- 封装网络请求工具:KJBannerViewDownloader
- 缓存工具:KJBannerViewCacheManager
- 网图下载工具:KJBannerViewLoadManager

### [版本1.3.8](https://github.com/yangKJ/KJBannerViewDemo/tree/1.3.8)
- 新增委托方法 `kj_BannerViewDidScroll:`

### [版本1.3.7](https://github.com/yangKJ/KJBannerViewDemo/tree/1.3.7)
- 新增动态图分类,替换原先的动态图播放方式
- 去掉单例,优化数据的获取方式
- 解决数据源为空的处理

### [版本1.3.6](https://github.com/yangKJ/KJBannerViewDemo/tree/1.3.6)
- KJPageView 新增属性 margin 用于方块之间微微调整
- KJPageView 新增属性 dotwidth和dotheight 用于方块尺寸调整
- KJPageView 优化解决不居中问题

### [版本1.3.5](https://github.com/yangKJ/KJBannerViewDemo/tree/1.3.5)
- 独立委托协议类KJBannerViewProtocol,归类代码更加简洁
- 新增滚动回调 `kScrollBlock`

### [版本1.3.4](https://github.com/yangKJ/KJBannerViewDemo/tree/1.3.4)
- 解决只有一张图片显示异常问题
- 多线程处理gif数据,再次提升效率

### [版本1.3.3](https://github.com/yangKJ/KJBannerViewDemo/tree/1.3.3)
- 优化图片下载速率,解决卡顿问题
- 修改`kj_BannerView:BannerViewCell:ImageDatas:Index:`委托方法,解决Memory疯涨问题

### [版本1.3.2](https://github.com/yangKJ/KJBannerViewDemo/tree/1.3.2)
- 新增 NSTimer+KJSolve 解决计时器循环引用

### [版本1.3.0](https://github.com/yangKJ/KJBannerViewDemo/tree/1.3.0)
- 新增KJBannerViewDataSource委托,更方便的自定义方式 不需要再继承 KJBannerViewCell
- `kj_BannerView:BannerViewCell:ImageDatas:Index:`此方法和 `itemClass` 互斥
- Banner支持在Storyboard和Xib中创建并配置其属性
- 新增裁剪网络图片从而提高效率 bannerScale

### [版本1.2.6](https://github.com/yangKJ/KJBannerViewDemo/tree/1.2.6)
- KJPageView 新增大小点类型 PageControlStyleSizeDot
- 优化修改网友提出的卡顿问题
- 移出 KJBannerViewCell 当中的判断处理,从而提高效率

### [版本1.2.5](https://github.com/yangKJ/KJBannerViewDemo/tree/1.2.5)
- 新增委托方法 `kj_BannerView:CurrentIndex:` 滚动时候回调 可是否隐藏自带的PageControl
- 优化性能,修复重复创建PageControl

### [版本1.2.4](https://github.com/yangKJ/KJBannerViewDemo/tree/1.2.4)
- 新增本地和网络图片混合,自带判断方式,去掉以前的本地判断方式
- 新增Gif图显示,支持本地图片、网络图片、网络GIF图片混合显示
- KJBannerViewImageType 控制图片的显示类型

### [版本1.2.2](https://github.com/yangKJ/KJBannerViewDemo/tree/1.2.2)
- 修改pageControl样式颜色的修改方式,从而提高效率

### [版本1.2.1](https://github.com/yangKJ/KJBannerViewDemo/tree/1.2.1)
- 再次优化,提高性能
- 新增自带Cell显示本地图片 `isLocalityImage`

### [版本1.2.0](https://github.com/yangKJ/KJBannerViewDemo/tree/1.2.0)
- KJPageView 支持3种样式(圆形,长方形,正方形)
- 重新整理,从而提高轮播图性能
- 自带Cell新增默认占位图,一条数据时隐藏KJPageControl

### [版本1.1.1](https://github.com/yangKJ/KJBannerViewDemo/tree/1.1.1)
- 新增支持Swift宏
- 新增Block代理点击事件 KJBannerViewBlock
- 新增设置滚动方向属性 `rollType`

### [版本1.1.0](https://github.com/yangKJ/KJBannerViewDemo/tree/1.1.0)
- 新增支持自定义Cell
- 继承KJBannerViewCell,然后在model设置数据

### 版本1.0.2
- 新增 KJBannerView 轮播图 - banner支持缩放
- 自带图片下载和缓存相关功能,无三方依赖、轻量级组件

# <a id="作者信息"></a>作者信息
### [Github地址](https://github.com/yangKJ) | [简书地址](https://www.jianshu.com/u/c84c00476ab6) | [博客地址](https://blog.csdn.net/qq_34534179) | [掘金地址](https://juejin.cn/user/1987535102554472/posts)


================================================
FILE: KJBannerView.podspec
================================================
Pod::Spec.new do |s|
  s.name         = "KJBannerView"
  s.version      = "3.1.0"
  s.summary      = "KJBannerView是一款自带图片下载和缓存轮播Banner,支持动态图和网图混合显示"
  s.homepage     = "https://github.com/yangKJ/KJBannerViewDemo"
  s.license      = "MIT"
  s.license      = {:type => "MIT", :file => "LICENSE"}
  s.license      = "Copyright (c) 2018 yangkejun"
  s.author       = {"77" => "ykj310@126.com"}
  s.source       = {:git => "https://github.com/yangKJ/KJBannerViewDemo.git", :tag => "#{s.version}"}
  s.platform     = :ios
  s.requires_arc = true
  s.static_framework = true
  s.ios.deployment_target = '9.0'
  s.ios.pod_target_xcconfig = { 'PRODUCT_BUNDLE_IDENTIFIER' => 'com.yangkejun.KJBannerViewDemo' }
  
  s.default_subspec  = 'BannerView'
  s.ios.source_files = 'Sources/KJBannerHeader.h'

  s.subspec 'BannerView' do |ss|
    ss.source_files = "Sources/KJBannerView/*.{h,m}","Sources/PageControl/*.{h,m}"
    ss.resources = "Sources/KJBannerView/*.{bundle}"
  end
  
  s.subspec 'Downloader' do |ss|
    ss.source_files = "Sources/WebImage/*.{h,m}"
  end
  
end


================================================
FILE: KJBannerViewDemo/AppDelegate.h
================================================
//
//  AppDelegate.h
//  KJBannerViewDemo
//
//  Created by 杨科军 on 2018/12/22.
//  Copyright © 2018 杨科军. All rights reserved.
//  https://github.com/yangKJ/KJBannerViewDemo

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;


@end



================================================
FILE: KJBannerViewDemo/AppDelegate.m
================================================
//
//  AppDelegate.m
//  KJBannerViewDemo
//
//  Created by 杨科军 on 2018/12/22.
//  Copyright © 2018 杨科军. All rights reserved.
//  https://github.com/yangKJ/KJBannerViewDemo

#import "AppDelegate.h"
#import "KJWebImageHeader.h"

@interface AppDelegate ()

@end

@implementation AppDelegate


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    
    //清除三天前缓存的数据
    [KJAutoPurgingCache autoPurgingCache:YES timingTimeType:(KJAutoPurginCacheTypeThreeDay)];
    
    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: KJBannerViewDemo/Masonry/MASCompositeConstraint.h
================================================
//
//  MASCompositeConstraint.h
//  Masonry
//
//  Created by Jonas Budelmann on 21/07/13.
//  Copyright (c) 2013 cloudling. All rights reserved.
//

#import "MASConstraint.h"
#import "MASUtilities.h"

/**
 *	A group of MASConstraint objects
 */
@interface MASCompositeConstraint : MASConstraint

/**
 *	Creates a composite with a predefined array of children
 *
 *	@param	children	child MASConstraints
 *
 *	@return	a composite constraint
 */
- (id)initWithChildren:(NSArray *)children;

@end


================================================
FILE: KJBannerViewDemo/Masonry/MASCompositeConstraint.m
================================================
//
//  MASCompositeConstraint.m
//  Masonry
//
//  Created by Jonas Budelmann on 21/07/13.
//  Copyright (c) 2013 cloudling. All rights reserved.
//

#import "MASCompositeConstraint.h"
#import "MASConstraint+Private.h"

@interface MASCompositeConstraint () <MASConstraintDelegate>

@property (nonatomic, strong) id mas_key;
@property (nonatomic, strong) NSMutableArray *childConstraints;

@end

@implementation MASCompositeConstraint

- (id)initWithChildren:(NSArray *)children {
    self = [super init];
    if (!self) return nil;

    _childConstraints = [children mutableCopy];
    for (MASConstraint *constraint in _childConstraints) {
        constraint.delegate = self;
    }

    return self;
}

#pragma mark - MASConstraintDelegate

- (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint {
    NSUInteger index = [self.childConstraints indexOfObject:constraint];
    NSAssert(index != NSNotFound, @"Could not find constraint %@", constraint);
    [self.childConstraints replaceObjectAtIndex:index withObject:replacementConstraint];
}

- (MASConstraint *)constraint:(MASConstraint __unused *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
    id<MASConstraintDelegate> strongDelegate = self.delegate;
    MASConstraint *newConstraint = [strongDelegate constraint:self addConstraintWithLayoutAttribute:layoutAttribute];
    newConstraint.delegate = self;
    [self.childConstraints addObject:newConstraint];
    return newConstraint;
}

#pragma mark - NSLayoutConstraint multiplier proxies 

- (MASConstraint * (^)(CGFloat))multipliedBy {
    return ^id(CGFloat multiplier) {
        for (MASConstraint *constraint in self.childConstraints) {
            constraint.multipliedBy(multiplier);
        }
        return self;
    };
}

- (MASConstraint * (^)(CGFloat))dividedBy {
    return ^id(CGFloat divider) {
        for (MASConstraint *constraint in self.childConstraints) {
            constraint.dividedBy(divider);
        }
        return self;
    };
}

#pragma mark - MASLayoutPriority proxy

- (MASConstraint * (^)(MASLayoutPriority))priority {
    return ^id(MASLayoutPriority priority) {
        for (MASConstraint *constraint in self.childConstraints) {
            constraint.priority(priority);
        }
        return self;
    };
}

#pragma mark - NSLayoutRelation proxy

- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation {
    return ^id(id attr, NSLayoutRelation relation) {
        for (MASConstraint *constraint in self.childConstraints.copy) {
            constraint.equalToWithRelation(attr, relation);
        }
        return self;
    };
}

#pragma mark - attribute chaining

- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
    [self constraint:self addConstraintWithLayoutAttribute:layoutAttribute];
    return self;
}

#pragma mark - Animator proxy

#if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV)

- (MASConstraint *)animator {
    for (MASConstraint *constraint in self.childConstraints) {
        [constraint animator];
    }
    return self;
}

#endif

#pragma mark - debug helpers

- (MASConstraint * (^)(id))key {
    return ^id(id key) {
        self.mas_key = key;
        int i = 0;
        for (MASConstraint *constraint in self.childConstraints) {
            constraint.key([NSString stringWithFormat:@"%@[%d]", key, i++]);
        }
        return self;
    };
}

#pragma mark - NSLayoutConstraint constant setters

- (void)setInsets:(MASEdgeInsets)insets {
    for (MASConstraint *constraint in self.childConstraints) {
        constraint.insets = insets;
    }
}

- (void)setInset:(CGFloat)inset {
    for (MASConstraint *constraint in self.childConstraints) {
        constraint.inset = inset;
    }
}

- (void)setOffset:(CGFloat)offset {
    for (MASConstraint *constraint in self.childConstraints) {
        constraint.offset = offset;
    }
}

- (void)setSizeOffset:(CGSize)sizeOffset {
    for (MASConstraint *constraint in self.childConstraints) {
        constraint.sizeOffset = sizeOffset;
    }
}

- (void)setCenterOffset:(CGPoint)centerOffset {
    for (MASConstraint *constraint in self.childConstraints) {
        constraint.centerOffset = centerOffset;
    }
}

#pragma mark - MASConstraint

- (void)activate {
    for (MASConstraint *constraint in self.childConstraints) {
        [constraint activate];
    }
}

- (void)deactivate {
    for (MASConstraint *constraint in self.childConstraints) {
        [constraint deactivate];
    }
}

- (void)install {
    for (MASConstraint *constraint in self.childConstraints) {
        constraint.updateExisting = self.updateExisting;
        [constraint install];
    }
}

- (void)uninstall {
    for (MASConstraint *constraint in self.childConstraints) {
        [constraint uninstall];
    }
}

@end


================================================
FILE: KJBannerViewDemo/Masonry/MASConstraint+Private.h
================================================
//
//  MASConstraint+Private.h
//  Masonry
//
//  Created by Nick Tymchenko on 29/04/14.
//  Copyright (c) 2014 cloudling. All rights reserved.
//

#import "MASConstraint.h"

@protocol MASConstraintDelegate;


@interface MASConstraint ()

/**
 *  Whether or not to check for an existing constraint instead of adding constraint
 */
@property (nonatomic, assign) BOOL updateExisting;

/**
 *	Usually MASConstraintMaker but could be a parent MASConstraint
 */
@property (nonatomic, weak) id<MASConstraintDelegate> delegate;

/**
 *  Based on a provided value type, is equal to calling:
 *  NSNumber - setOffset:
 *  NSValue with CGPoint - setPointOffset:
 *  NSValue with CGSize - setSizeOffset:
 *  NSValue with MASEdgeInsets - setInsets:
 */
- (void)setLayoutConstantWithValue:(NSValue *)value;

@end


@interface MASConstraint (Abstract)

/**
 *	Sets the constraint relation to given NSLayoutRelation
 *  returns a block which accepts one of the following:
 *    MASViewAttribute, UIView, NSValue, NSArray
 *  see readme for more details.
 */
- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation;

/**
 *	Override to set a custom chaining behaviour
 */
- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute;

@end


@protocol MASConstraintDelegate <NSObject>

/**
 *	Notifies the delegate when the constraint needs to be replaced with another constraint. For example
 *  A MASViewConstraint may turn into a MASCompositeConstraint when an array is passed to one of the equality blocks
 */
- (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint;

- (MASConstraint *)constraint:(MASConstraint *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute;

@end


================================================
FILE: KJBannerViewDemo/Masonry/MASConstraint.h
================================================
//
//  MASConstraint.h
//  Masonry
//
//  Created by Jonas Budelmann on 22/07/13.
//  Copyright (c) 2013 cloudling. All rights reserved.
//

#import "MASUtilities.h"

/**
 *	Enables Constraints to be created with chainable syntax
 *  Constraint can represent single NSLayoutConstraint (MASViewConstraint) 
 *  or a group of NSLayoutConstraints (MASComposisteConstraint)
 */
@interface MASConstraint : NSObject

// Chaining Support

/**
 *	Modifies the NSLayoutConstraint constant,
 *  only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
 *  NSLayoutAttributeTop, NSLayoutAttributeLeft, NSLayoutAttributeBottom, NSLayoutAttributeRight
 */
- (MASConstraint * (^)(MASEdgeInsets insets))insets;

/**
 *	Modifies the NSLayoutConstraint constant,
 *  only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
 *  NSLayoutAttributeTop, NSLayoutAttributeLeft, NSLayoutAttributeBottom, NSLayoutAttributeRight
 */
- (MASConstraint * (^)(CGFloat inset))inset;

/**
 *	Modifies the NSLayoutConstraint constant,
 *  only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
 *  NSLayoutAttributeWidth, NSLayoutAttributeHeight
 */
- (MASConstraint * (^)(CGSize offset))sizeOffset;

/**
 *	Modifies the NSLayoutConstraint constant,
 *  only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
 *  NSLayoutAttributeCenterX, NSLayoutAttributeCenterY
 */
- (MASConstraint * (^)(CGPoint offset))centerOffset;

/**
 *	Modifies the NSLayoutConstraint constant
 */
- (MASConstraint * (^)(CGFloat offset))offset;

/**
 *  Modifies the NSLayoutConstraint constant based on a value type
 */
- (MASConstraint * (^)(NSValue *value))valueOffset;

/**
 *	Sets the NSLayoutConstraint multiplier property
 */
- (MASConstraint * (^)(CGFloat multiplier))multipliedBy;

/**
 *	Sets the NSLayoutConstraint multiplier to 1.0/dividedBy
 */
- (MASConstraint * (^)(CGFloat divider))dividedBy;

/**
 *	Sets the NSLayoutConstraint priority to a float or MASLayoutPriority
 */
- (MASConstraint * (^)(MASLayoutPriority priority))priority;

/**
 *	Sets the NSLayoutConstraint priority to MASLayoutPriorityLow
 */
- (MASConstraint * (^)(void))priorityLow;

/**
 *	Sets the NSLayoutConstraint priority to MASLayoutPriorityMedium
 */
- (MASConstraint * (^)(void))priorityMedium;

/**
 *	Sets the NSLayoutConstraint priority to MASLayoutPriorityHigh
 */
- (MASConstraint * (^)(void))priorityHigh;

/**
 *	Sets the constraint relation to NSLayoutRelationEqual
 *  returns a block which accepts one of the following:
 *    MASViewAttribute, UIView, NSValue, NSArray
 *  see readme for more details.
 */
- (MASConstraint * (^)(id attr))equalTo;

/**
 *	Sets the constraint relation to NSLayoutRelationGreaterThanOrEqual
 *  returns a block which accepts one of the following:
 *    MASViewAttribute, UIView, NSValue, NSArray
 *  see readme for more details.
 */
- (MASConstraint * (^)(id attr))greaterThanOrEqualTo;

/**
 *	Sets the constraint relation to NSLayoutRelationLessThanOrEqual
 *  returns a block which accepts one of the following:
 *    MASViewAttribute, UIView, NSValue, NSArray
 *  see readme for more details.
 */
- (MASConstraint * (^)(id attr))lessThanOrEqualTo;

/**
 *	Optional semantic property which has no effect but improves the readability of constraint
 */
- (MASConstraint *)with;

/**
 *	Optional semantic property which has no effect but improves the readability of constraint
 */
- (MASConstraint *)and;

/**
 *	Creates a new MASCompositeConstraint with the called attribute and reciever
 */
- (MASConstraint *)left;
- (MASConstraint *)top;
- (MASConstraint *)right;
- (MASConstraint *)bottom;
- (MASConstraint *)leading;
- (MASConstraint *)trailing;
- (MASConstraint *)width;
- (MASConstraint *)height;
- (MASConstraint *)centerX;
- (MASConstraint *)centerY;
- (MASConstraint *)baseline;

#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100)

- (MASConstraint *)firstBaseline;
- (MASConstraint *)lastBaseline;

#endif

#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000)

- (MASConstraint *)leftMargin;
- (MASConstraint *)rightMargin;
- (MASConstraint *)topMargin;
- (MASConstraint *)bottomMargin;
- (MASConstraint *)leadingMargin;
- (MASConstraint *)trailingMargin;
- (MASConstraint *)centerXWithinMargins;
- (MASConstraint *)centerYWithinMargins;

#endif


/**
 *	Sets the constraint debug name
 */
- (MASConstraint * (^)(id key))key;

// NSLayoutConstraint constant Setters
// for use outside of mas_updateConstraints/mas_makeConstraints blocks

/**
 *	Modifies the NSLayoutConstraint constant,
 *  only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
 *  NSLayoutAttributeTop, NSLayoutAttributeLeft, NSLayoutAttributeBottom, NSLayoutAttributeRight
 */
- (void)setInsets:(MASEdgeInsets)insets;

/**
 *	Modifies the NSLayoutConstraint constant,
 *  only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
 *  NSLayoutAttributeTop, NSLayoutAttributeLeft, NSLayoutAttributeBottom, NSLayoutAttributeRight
 */
- (void)setInset:(CGFloat)inset;

/**
 *	Modifies the NSLayoutConstraint constant,
 *  only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
 *  NSLayoutAttributeWidth, NSLayoutAttributeHeight
 */
- (void)setSizeOffset:(CGSize)sizeOffset;

/**
 *	Modifies the NSLayoutConstraint constant,
 *  only affects MASConstraints in which the first item's NSLayoutAttribute is one of the following
 *  NSLayoutAttributeCenterX, NSLayoutAttributeCenterY
 */
- (void)setCenterOffset:(CGPoint)centerOffset;

/**
 *	Modifies the NSLayoutConstraint constant
 */
- (void)setOffset:(CGFloat)offset;


// NSLayoutConstraint Installation support

#if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV)
/**
 *  Whether or not to go through the animator proxy when modifying the constraint
 */
@property (nonatomic, copy, readonly) MASConstraint *animator;
#endif

/**
 *  Activates an NSLayoutConstraint if it's supported by an OS. 
 *  Invokes install otherwise.
 */
- (void)activate;

/**
 *  Deactivates previously installed/activated NSLayoutConstraint.
 */
- (void)deactivate;

/**
 *	Creates a NSLayoutConstraint and adds it to the appropriate view.
 */
- (void)install;

/**
 *	Removes previously installed NSLayoutConstraint
 */
- (void)uninstall;

@end


/**
 *  Convenience auto-boxing macros for MASConstraint methods.
 *
 *  Defining MAS_SHORTHAND_GLOBALS will turn on auto-boxing for default syntax.
 *  A potential drawback of this is that the unprefixed macros will appear in global scope.
 */
#define mas_equalTo(...)                 equalTo(MASBoxValue((__VA_ARGS__)))
#define mas_greaterThanOrEqualTo(...)    greaterThanOrEqualTo(MASBoxValue((__VA_ARGS__)))
#define mas_lessThanOrEqualTo(...)       lessThanOrEqualTo(MASBoxValue((__VA_ARGS__)))

#define mas_offset(...)                  valueOffset(MASBoxValue((__VA_ARGS__)))


#ifdef MAS_SHORTHAND_GLOBALS

#define equalTo(...)                     mas_equalTo(__VA_ARGS__)
#define greaterThanOrEqualTo(...)        mas_greaterThanOrEqualTo(__VA_ARGS__)
#define lessThanOrEqualTo(...)           mas_lessThanOrEqualTo(__VA_ARGS__)

#define offset(...)                      mas_offset(__VA_ARGS__)

#endif


@interface MASConstraint (AutoboxingSupport)

/**
 *  Aliases to corresponding relation methods (for shorthand macros)
 *  Also needed to aid autocompletion
 */
- (MASConstraint * (^)(id attr))mas_equalTo;
- (MASConstraint * (^)(id attr))mas_greaterThanOrEqualTo;
- (MASConstraint * (^)(id attr))mas_lessThanOrEqualTo;

/**
 *  A dummy method to aid autocompletion
 */
- (MASConstraint * (^)(id offset))mas_offset;

@end


================================================
FILE: KJBannerViewDemo/Masonry/MASConstraint.m
================================================
//
//  MASConstraint.m
//  Masonry
//
//  Created by Nick Tymchenko on 1/20/14.
//

#import "MASConstraint.h"
#import "MASConstraint+Private.h"

#define MASMethodNotImplemented() \
    @throw [NSException exceptionWithName:NSInternalInconsistencyException \
                                   reason:[NSString stringWithFormat:@"You must override %@ in a subclass.", NSStringFromSelector(_cmd)] \
                                 userInfo:nil]

@implementation MASConstraint

#pragma mark - Init

- (id)init {
	NSAssert(![self isMemberOfClass:[MASConstraint class]], @"MASConstraint is an abstract class, you should not instantiate it directly.");
	return [super init];
}

#pragma mark - NSLayoutRelation proxies

- (MASConstraint * (^)(id))equalTo {
    return ^id(id attribute) {
        return self.equalToWithRelation(attribute, NSLayoutRelationEqual);
    };
}

- (MASConstraint * (^)(id))mas_equalTo {
    return ^id(id attribute) {
        return self.equalToWithRelation(attribute, NSLayoutRelationEqual);
    };
}

- (MASConstraint * (^)(id))greaterThanOrEqualTo {
    return ^id(id attribute) {
        return self.equalToWithRelation(attribute, NSLayoutRelationGreaterThanOrEqual);
    };
}

- (MASConstraint * (^)(id))mas_greaterThanOrEqualTo {
    return ^id(id attribute) {
        return self.equalToWithRelation(attribute, NSLayoutRelationGreaterThanOrEqual);
    };
}

- (MASConstraint * (^)(id))lessThanOrEqualTo {
    return ^id(id attribute) {
        return self.equalToWithRelation(attribute, NSLayoutRelationLessThanOrEqual);
    };
}

- (MASConstraint * (^)(id))mas_lessThanOrEqualTo {
    return ^id(id attribute) {
        return self.equalToWithRelation(attribute, NSLayoutRelationLessThanOrEqual);
    };
}

#pragma mark - MASLayoutPriority proxies

- (MASConstraint * (^)(void))priorityLow {
    return ^id{
        self.priority(MASLayoutPriorityDefaultLow);
        return self;
    };
}

- (MASConstraint * (^)(void))priorityMedium {
    return ^id{
        self.priority(MASLayoutPriorityDefaultMedium);
        return self;
    };
}

- (MASConstraint * (^)(void))priorityHigh {
    return ^id{
        self.priority(MASLayoutPriorityDefaultHigh);
        return self;
    };
}

#pragma mark - NSLayoutConstraint constant proxies

- (MASConstraint * (^)(MASEdgeInsets))insets {
    return ^id(MASEdgeInsets insets){
        self.insets = insets;
        return self;
    };
}

- (MASConstraint * (^)(CGFloat))inset {
    return ^id(CGFloat inset){
        self.inset = inset;
        return self;
    };
}

- (MASConstraint * (^)(CGSize))sizeOffset {
    return ^id(CGSize offset) {
        self.sizeOffset = offset;
        return self;
    };
}

- (MASConstraint * (^)(CGPoint))centerOffset {
    return ^id(CGPoint offset) {
        self.centerOffset = offset;
        return self;
    };
}

- (MASConstraint * (^)(CGFloat))offset {
    return ^id(CGFloat offset){
        self.offset = offset;
        return self;
    };
}

- (MASConstraint * (^)(NSValue *value))valueOffset {
    return ^id(NSValue *offset) {
        NSAssert([offset isKindOfClass:NSValue.class], @"expected an NSValue offset, got: %@", offset);
        [self setLayoutConstantWithValue:offset];
        return self;
    };
}

- (MASConstraint * (^)(id offset))mas_offset {
    // Will never be called due to macro
    return nil;
}

#pragma mark - NSLayoutConstraint constant setter

- (void)setLayoutConstantWithValue:(NSValue *)value {
    if ([value isKindOfClass:NSNumber.class]) {
        self.offset = [(NSNumber *)value doubleValue];
    } else if (strcmp(value.objCType, @encode(CGPoint)) == 0) {
        CGPoint point;
        [value getValue:&point];
        self.centerOffset = point;
    } else if (strcmp(value.objCType, @encode(CGSize)) == 0) {
        CGSize size;
        [value getValue:&size];
        self.sizeOffset = size;
    } else if (strcmp(value.objCType, @encode(MASEdgeInsets)) == 0) {
        MASEdgeInsets insets;
        [value getValue:&insets];
        self.insets = insets;
    } else {
        NSAssert(NO, @"attempting to set layout constant with unsupported value: %@", value);
    }
}

#pragma mark - Semantic properties

- (MASConstraint *)with {
    return self;
}

- (MASConstraint *)and {
    return self;
}

#pragma mark - Chaining

- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute __unused)layoutAttribute {
    MASMethodNotImplemented();
}

- (MASConstraint *)left {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft];
}

- (MASConstraint *)top {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTop];
}

- (MASConstraint *)right {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRight];
}

- (MASConstraint *)bottom {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottom];
}

- (MASConstraint *)leading {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeading];
}

- (MASConstraint *)trailing {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailing];
}

- (MASConstraint *)width {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeWidth];
}

- (MASConstraint *)height {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeHeight];
}

- (MASConstraint *)centerX {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterX];
}

- (MASConstraint *)centerY {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterY];
}

- (MASConstraint *)baseline {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBaseline];
}

#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100)

- (MASConstraint *)firstBaseline {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeFirstBaseline];
}
- (MASConstraint *)lastBaseline {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLastBaseline];
}

#endif

#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000)

- (MASConstraint *)leftMargin {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeftMargin];
}

- (MASConstraint *)rightMargin {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRightMargin];
}

- (MASConstraint *)topMargin {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTopMargin];
}

- (MASConstraint *)bottomMargin {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottomMargin];
}

- (MASConstraint *)leadingMargin {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeadingMargin];
}

- (MASConstraint *)trailingMargin {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailingMargin];
}

- (MASConstraint *)centerXWithinMargins {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterXWithinMargins];
}

- (MASConstraint *)centerYWithinMargins {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterYWithinMargins];
}

#endif

#pragma mark - Abstract

- (MASConstraint * (^)(CGFloat multiplier))multipliedBy { MASMethodNotImplemented(); }

- (MASConstraint * (^)(CGFloat divider))dividedBy { MASMethodNotImplemented(); }

- (MASConstraint * (^)(MASLayoutPriority priority))priority { MASMethodNotImplemented(); }

- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation { MASMethodNotImplemented(); }

- (MASConstraint * (^)(id key))key { MASMethodNotImplemented(); }

- (void)setInsets:(MASEdgeInsets __unused)insets { MASMethodNotImplemented(); }

- (void)setInset:(CGFloat __unused)inset { MASMethodNotImplemented(); }

- (void)setSizeOffset:(CGSize __unused)sizeOffset { MASMethodNotImplemented(); }

- (void)setCenterOffset:(CGPoint __unused)centerOffset { MASMethodNotImplemented(); }

- (void)setOffset:(CGFloat __unused)offset { MASMethodNotImplemented(); }

#if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV)

- (MASConstraint *)animator { MASMethodNotImplemented(); }

#endif

- (void)activate { MASMethodNotImplemented(); }

- (void)deactivate { MASMethodNotImplemented(); }

- (void)install { MASMethodNotImplemented(); }

- (void)uninstall { MASMethodNotImplemented(); }

@end


================================================
FILE: KJBannerViewDemo/Masonry/MASConstraintMaker.h
================================================
//
//  MASConstraintMaker.h
//  Masonry
//
//  Created by Jonas Budelmann on 20/07/13.
//  Copyright (c) 2013 cloudling. All rights reserved.
//

#import "MASConstraint.h"
#import "MASUtilities.h"

typedef NS_OPTIONS(NSInteger, MASAttribute) {
    MASAttributeLeft = 1 << NSLayoutAttributeLeft,
    MASAttributeRight = 1 << NSLayoutAttributeRight,
    MASAttributeTop = 1 << NSLayoutAttributeTop,
    MASAttributeBottom = 1 << NSLayoutAttributeBottom,
    MASAttributeLeading = 1 << NSLayoutAttributeLeading,
    MASAttributeTrailing = 1 << NSLayoutAttributeTrailing,
    MASAttributeWidth = 1 << NSLayoutAttributeWidth,
    MASAttributeHeight = 1 << NSLayoutAttributeHeight,
    MASAttributeCenterX = 1 << NSLayoutAttributeCenterX,
    MASAttributeCenterY = 1 << NSLayoutAttributeCenterY,
    MASAttributeBaseline = 1 << NSLayoutAttributeBaseline,
    
#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100)
    
    MASAttributeFirstBaseline = 1 << NSLayoutAttributeFirstBaseline,
    MASAttributeLastBaseline = 1 << NSLayoutAttributeLastBaseline,
    
#endif
    
#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000)
    
    MASAttributeLeftMargin = 1 << NSLayoutAttributeLeftMargin,
    MASAttributeRightMargin = 1 << NSLayoutAttributeRightMargin,
    MASAttributeTopMargin = 1 << NSLayoutAttributeTopMargin,
    MASAttributeBottomMargin = 1 << NSLayoutAttributeBottomMargin,
    MASAttributeLeadingMargin = 1 << NSLayoutAttributeLeadingMargin,
    MASAttributeTrailingMargin = 1 << NSLayoutAttributeTrailingMargin,
    MASAttributeCenterXWithinMargins = 1 << NSLayoutAttributeCenterXWithinMargins,
    MASAttributeCenterYWithinMargins = 1 << NSLayoutAttributeCenterYWithinMargins,

#endif
    
};

/**
 *  Provides factory methods for creating MASConstraints.
 *  Constraints are collected until they are ready to be installed
 *
 */
@interface MASConstraintMaker : NSObject

/**
 *	The following properties return a new MASViewConstraint
 *  with the first item set to the makers associated view and the appropriate MASViewAttribute
 */
@property (nonatomic, strong, readonly) MASConstraint *left;
@property (nonatomic, strong, readonly) MASConstraint *top;
@property (nonatomic, strong, readonly) MASConstraint *right;
@property (nonatomic, strong, readonly) MASConstraint *bottom;
@property (nonatomic, strong, readonly) MASConstraint *leading;
@property (nonatomic, strong, readonly) MASConstraint *trailing;
@property (nonatomic, strong, readonly) MASConstraint *width;
@property (nonatomic, strong, readonly) MASConstraint *height;
@property (nonatomic, strong, readonly) MASConstraint *centerX;
@property (nonatomic, strong, readonly) MASConstraint *centerY;
@property (nonatomic, strong, readonly) MASConstraint *baseline;

#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100)

@property (nonatomic, strong, readonly) MASConstraint *firstBaseline;
@property (nonatomic, strong, readonly) MASConstraint *lastBaseline;

#endif

#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000)

@property (nonatomic, strong, readonly) MASConstraint *leftMargin;
@property (nonatomic, strong, readonly) MASConstraint *rightMargin;
@property (nonatomic, strong, readonly) MASConstraint *topMargin;
@property (nonatomic, strong, readonly) MASConstraint *bottomMargin;
@property (nonatomic, strong, readonly) MASConstraint *leadingMargin;
@property (nonatomic, strong, readonly) MASConstraint *trailingMargin;
@property (nonatomic, strong, readonly) MASConstraint *centerXWithinMargins;
@property (nonatomic, strong, readonly) MASConstraint *centerYWithinMargins;

#endif

/**
 *  Returns a block which creates a new MASCompositeConstraint with the first item set
 *  to the makers associated view and children corresponding to the set bits in the
 *  MASAttribute parameter. Combine multiple attributes via binary-or.
 */
@property (nonatomic, strong, readonly) MASConstraint *(^attributes)(MASAttribute attrs);

/**
 *	Creates a MASCompositeConstraint with type MASCompositeConstraintTypeEdges
 *  which generates the appropriate MASViewConstraint children (top, left, bottom, right)
 *  with the first item set to the makers associated view
 */
@property (nonatomic, strong, readonly) MASConstraint *edges;

/**
 *	Creates a MASCompositeConstraint with type MASCompositeConstraintTypeSize
 *  which generates the appropriate MASViewConstraint children (width, height)
 *  with the first item set to the makers associated view
 */
@property (nonatomic, strong, readonly) MASConstraint *size;

/**
 *	Creates a MASCompositeConstraint with type MASCompositeConstraintTypeCenter
 *  which generates the appropriate MASViewConstraint children (centerX, centerY)
 *  with the first item set to the makers associated view
 */
@property (nonatomic, strong, readonly) MASConstraint *center;

/**
 *  Whether or not to check for an existing constraint instead of adding constraint
 */
@property (nonatomic, assign) BOOL updateExisting;

/**
 *  Whether or not to remove existing constraints prior to installing
 */
@property (nonatomic, assign) BOOL removeExisting;

/**
 *	initialises the maker with a default view
 *
 *	@param	view	any MASConstraint are created with this view as the first item
 *
 *	@return	a new MASConstraintMaker
 */
- (id)initWithView:(MAS_VIEW *)view;

/**
 *	Calls install method on any MASConstraints which have been created by this maker
 *
 *	@return	an array of all the installed MASConstraints
 */
- (NSArray *)install;

- (MASConstraint * (^)(dispatch_block_t))group;

@end


================================================
FILE: KJBannerViewDemo/Masonry/MASConstraintMaker.m
================================================
//
//  MASConstraintMaker.m
//  Masonry
//
//  Created by Jonas Budelmann on 20/07/13.
//  Copyright (c) 2013 cloudling. All rights reserved.
//

#import "MASConstraintMaker.h"
#import "MASViewConstraint.h"
#import "MASCompositeConstraint.h"
#import "MASConstraint+Private.h"
#import "MASViewAttribute.h"
#import "View+MASAdditions.h"

@interface MASConstraintMaker () <MASConstraintDelegate>

@property (nonatomic, weak) MAS_VIEW *view;
@property (nonatomic, strong) NSMutableArray *constraints;

@end

@implementation MASConstraintMaker

- (id)initWithView:(MAS_VIEW *)view {
    self = [super init];
    if (!self) return nil;
    
    self.view = view;
    self.constraints = NSMutableArray.new;
    
    return self;
}

- (NSArray *)install {
    if (self.removeExisting) {
        NSArray *installedConstraints = [MASViewConstraint installedConstraintsForView:self.view];
        for (MASConstraint *constraint in installedConstraints) {
            [constraint uninstall];
        }
    }
    NSArray *constraints = self.constraints.copy;
    for (MASConstraint *constraint in constraints) {
        constraint.updateExisting = self.updateExisting;
        [constraint install];
    }
    [self.constraints removeAllObjects];
    return constraints;
}

#pragma mark - MASConstraintDelegate

- (void)constraint:(MASConstraint *)constraint shouldBeReplacedWithConstraint:(MASConstraint *)replacementConstraint {
    NSUInteger index = [self.constraints indexOfObject:constraint];
    NSAssert(index != NSNotFound, @"Could not find constraint %@", constraint);
    [self.constraints replaceObjectAtIndex:index withObject:replacementConstraint];
}

- (MASConstraint *)constraint:(MASConstraint *)constraint addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
    MASViewAttribute *viewAttribute = [[MASViewAttribute alloc] initWithView:self.view layoutAttribute:layoutAttribute];
    MASViewConstraint *newConstraint = [[MASViewConstraint alloc] initWithFirstViewAttribute:viewAttribute];
    if ([constraint isKindOfClass:MASViewConstraint.class]) {
        //replace with composite constraint
        NSArray *children = @[constraint, newConstraint];
        MASCompositeConstraint *compositeConstraint = [[MASCompositeConstraint alloc] initWithChildren:children];
        compositeConstraint.delegate = self;
        [self constraint:constraint shouldBeReplacedWithConstraint:compositeConstraint];
        return compositeConstraint;
    }
    if (!constraint) {
        newConstraint.delegate = self;
        [self.constraints addObject:newConstraint];
    }
    return newConstraint;
}

- (MASConstraint *)addConstraintWithAttributes:(MASAttribute)attrs {
    __unused MASAttribute anyAttribute = (MASAttributeLeft | MASAttributeRight | MASAttributeTop | MASAttributeBottom | MASAttributeLeading
                                          | MASAttributeTrailing | MASAttributeWidth | MASAttributeHeight | MASAttributeCenterX
                                          | MASAttributeCenterY | MASAttributeBaseline
#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100)
                                          | MASAttributeFirstBaseline | MASAttributeLastBaseline
#endif
#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000)
                                          | MASAttributeLeftMargin | MASAttributeRightMargin | MASAttributeTopMargin | MASAttributeBottomMargin
                                          | MASAttributeLeadingMargin | MASAttributeTrailingMargin | MASAttributeCenterXWithinMargins
                                          | MASAttributeCenterYWithinMargins
#endif
                                          );
    
    NSAssert((attrs & anyAttribute) != 0, @"You didn't pass any attribute to make.attributes(...)");
    
    NSMutableArray *attributes = [NSMutableArray array];
    
    if (attrs & MASAttributeLeft) [attributes addObject:self.view.mas_left];
    if (attrs & MASAttributeRight) [attributes addObject:self.view.mas_right];
    if (attrs & MASAttributeTop) [attributes addObject:self.view.mas_top];
    if (attrs & MASAttributeBottom) [attributes addObject:self.view.mas_bottom];
    if (attrs & MASAttributeLeading) [attributes addObject:self.view.mas_leading];
    if (attrs & MASAttributeTrailing) [attributes addObject:self.view.mas_trailing];
    if (attrs & MASAttributeWidth) [attributes addObject:self.view.mas_width];
    if (attrs & MASAttributeHeight) [attributes addObject:self.view.mas_height];
    if (attrs & MASAttributeCenterX) [attributes addObject:self.view.mas_centerX];
    if (attrs & MASAttributeCenterY) [attributes addObject:self.view.mas_centerY];
    if (attrs & MASAttributeBaseline) [attributes addObject:self.view.mas_baseline];
    
#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100)
    
    if (attrs & MASAttributeFirstBaseline) [attributes addObject:self.view.mas_firstBaseline];
    if (attrs & MASAttributeLastBaseline) [attributes addObject:self.view.mas_lastBaseline];
    
#endif
    
#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000)
    
    if (attrs & MASAttributeLeftMargin) [attributes addObject:self.view.mas_leftMargin];
    if (attrs & MASAttributeRightMargin) [attributes addObject:self.view.mas_rightMargin];
    if (attrs & MASAttributeTopMargin) [attributes addObject:self.view.mas_topMargin];
    if (attrs & MASAttributeBottomMargin) [attributes addObject:self.view.mas_bottomMargin];
    if (attrs & MASAttributeLeadingMargin) [attributes addObject:self.view.mas_leadingMargin];
    if (attrs & MASAttributeTrailingMargin) [attributes addObject:self.view.mas_trailingMargin];
    if (attrs & MASAttributeCenterXWithinMargins) [attributes addObject:self.view.mas_centerXWithinMargins];
    if (attrs & MASAttributeCenterYWithinMargins) [attributes addObject:self.view.mas_centerYWithinMargins];
    
#endif
    
    NSMutableArray *children = [NSMutableArray arrayWithCapacity:attributes.count];
    
    for (MASViewAttribute *a in attributes) {
        [children addObject:[[MASViewConstraint alloc] initWithFirstViewAttribute:a]];
    }
    
    MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithChildren:children];
    constraint.delegate = self;
    [self.constraints addObject:constraint];
    return constraint;
}

#pragma mark - standard Attributes

- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
    return [self constraint:nil addConstraintWithLayoutAttribute:layoutAttribute];
}

- (MASConstraint *)left {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeft];
}

- (MASConstraint *)top {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTop];
}

- (MASConstraint *)right {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRight];
}

- (MASConstraint *)bottom {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottom];
}

- (MASConstraint *)leading {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeading];
}

- (MASConstraint *)trailing {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailing];
}

- (MASConstraint *)width {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeWidth];
}

- (MASConstraint *)height {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeHeight];
}

- (MASConstraint *)centerX {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterX];
}

- (MASConstraint *)centerY {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterY];
}

- (MASConstraint *)baseline {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBaseline];
}

- (MASConstraint *(^)(MASAttribute))attributes {
    return ^(MASAttribute attrs){
        return [self addConstraintWithAttributes:attrs];
    };
}

#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100)

- (MASConstraint *)firstBaseline {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeFirstBaseline];
}

- (MASConstraint *)lastBaseline {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLastBaseline];
}

#endif


#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000)

- (MASConstraint *)leftMargin {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeftMargin];
}

- (MASConstraint *)rightMargin {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeRightMargin];
}

- (MASConstraint *)topMargin {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTopMargin];
}

- (MASConstraint *)bottomMargin {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeBottomMargin];
}

- (MASConstraint *)leadingMargin {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeLeadingMargin];
}

- (MASConstraint *)trailingMargin {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeTrailingMargin];
}

- (MASConstraint *)centerXWithinMargins {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterXWithinMargins];
}

- (MASConstraint *)centerYWithinMargins {
    return [self addConstraintWithLayoutAttribute:NSLayoutAttributeCenterYWithinMargins];
}

#endif


#pragma mark - composite Attributes

- (MASConstraint *)edges {
    return [self addConstraintWithAttributes:MASAttributeTop | MASAttributeLeft | MASAttributeRight | MASAttributeBottom];
}

- (MASConstraint *)size {
    return [self addConstraintWithAttributes:MASAttributeWidth | MASAttributeHeight];
}

- (MASConstraint *)center {
    return [self addConstraintWithAttributes:MASAttributeCenterX | MASAttributeCenterY];
}

#pragma mark - grouping

- (MASConstraint *(^)(dispatch_block_t group))group {
    return ^id(dispatch_block_t group) {
        NSInteger previousCount = self.constraints.count;
        group();

        NSArray *children = [self.constraints subarrayWithRange:NSMakeRange(previousCount, self.constraints.count - previousCount)];
        MASCompositeConstraint *constraint = [[MASCompositeConstraint alloc] initWithChildren:children];
        constraint.delegate = self;
        return constraint;
    };
}

@end


================================================
FILE: KJBannerViewDemo/Masonry/MASLayoutConstraint.h
================================================
//
//  MASLayoutConstraint.h
//  Masonry
//
//  Created by Jonas Budelmann on 3/08/13.
//  Copyright (c) 2013 Jonas Budelmann. All rights reserved.
//

#import "MASUtilities.h"

/**
 *	When you are debugging or printing the constraints attached to a view this subclass
 *  makes it easier to identify which constraints have been created via Masonry
 */
@interface MASLayoutConstraint : NSLayoutConstraint

/**
 *	a key to associate with this constraint
 */
@property (nonatomic, strong) id mas_key;

@end


================================================
FILE: KJBannerViewDemo/Masonry/MASLayoutConstraint.m
================================================
//
//  MASLayoutConstraint.m
//  Masonry
//
//  Created by Jonas Budelmann on 3/08/13.
//  Copyright (c) 2013 Jonas Budelmann. All rights reserved.
//

#import "MASLayoutConstraint.h"

@implementation MASLayoutConstraint

@end


================================================
FILE: KJBannerViewDemo/Masonry/MASUtilities.h
================================================
//
//  MASUtilities.h
//  Masonry
//
//  Created by Jonas Budelmann on 19/08/13.
//  Copyright (c) 2013 Jonas Budelmann. All rights reserved.
//

#import <Foundation/Foundation.h>



#if TARGET_OS_IPHONE || TARGET_OS_TV

    #import <UIKit/UIKit.h>
    #define MAS_VIEW UIView
    #define MAS_VIEW_CONTROLLER UIViewController
    #define MASEdgeInsets UIEdgeInsets

    typedef UILayoutPriority MASLayoutPriority;
    static const MASLayoutPriority MASLayoutPriorityRequired = UILayoutPriorityRequired;
    static const MASLayoutPriority MASLayoutPriorityDefaultHigh = UILayoutPriorityDefaultHigh;
    static const MASLayoutPriority MASLayoutPriorityDefaultMedium = 500;
    static const MASLayoutPriority MASLayoutPriorityDefaultLow = UILayoutPriorityDefaultLow;
    static const MASLayoutPriority MASLayoutPriorityFittingSizeLevel = UILayoutPriorityFittingSizeLevel;

#elif TARGET_OS_MAC

    #import <AppKit/AppKit.h>
    #define MAS_VIEW NSView
    #define MASEdgeInsets NSEdgeInsets

    typedef NSLayoutPriority MASLayoutPriority;
    static const MASLayoutPriority MASLayoutPriorityRequired = NSLayoutPriorityRequired;
    static const MASLayoutPriority MASLayoutPriorityDefaultHigh = NSLayoutPriorityDefaultHigh;
    static const MASLayoutPriority MASLayoutPriorityDragThatCanResizeWindow = NSLayoutPriorityDragThatCanResizeWindow;
    static const MASLayoutPriority MASLayoutPriorityDefaultMedium = 501;
    static const MASLayoutPriority MASLayoutPriorityWindowSizeStayPut = NSLayoutPriorityWindowSizeStayPut;
    static const MASLayoutPriority MASLayoutPriorityDragThatCannotResizeWindow = NSLayoutPriorityDragThatCannotResizeWindow;
    static const MASLayoutPriority MASLayoutPriorityDefaultLow = NSLayoutPriorityDefaultLow;
    static const MASLayoutPriority MASLayoutPriorityFittingSizeCompression = NSLayoutPriorityFittingSizeCompression;

#endif

/**
 *	Allows you to attach keys to objects matching the variable names passed.
 *
 *  view1.mas_key = @"view1", view2.mas_key = @"view2";
 *
 *  is equivalent to:
 *
 *  MASAttachKeys(view1, view2);
 */
#define MASAttachKeys(...)                                                        \
    {                                                                             \
        NSDictionary *keyPairs = NSDictionaryOfVariableBindings(__VA_ARGS__);     \
        for (id key in keyPairs.allKeys) {                                        \
            id obj = keyPairs[key];                                               \
            NSAssert([obj respondsToSelector:@selector(setMas_key:)],             \
                     @"Cannot attach mas_key to %@", obj);                        \
            [obj setMas_key:key];                                                 \
        }                                                                         \
    }

/**
 *  Used to create object hashes
 *  Based on http://www.mikeash.com/pyblog/friday-qa-2010-06-18-implementing-equality-and-hashing.html
 */
#define MAS_NSUINT_BIT (CHAR_BIT * sizeof(NSUInteger))
#define MAS_NSUINTROTATE(val, howmuch) ((((NSUInteger)val) << howmuch) | (((NSUInteger)val) >> (MAS_NSUINT_BIT - howmuch)))

/**
 *  Given a scalar or struct value, wraps it in NSValue
 *  Based on EXPObjectify: https://github.com/specta/expecta
 */
static inline id _MASBoxValue(const char *type, ...) {
    va_list v;
    va_start(v, type);
    id obj = nil;
    if (strcmp(type, @encode(id)) == 0) {
        id actual = va_arg(v, id);
        obj = actual;
    } else if (strcmp(type, @encode(CGPoint)) == 0) {
        CGPoint actual = (CGPoint)va_arg(v, CGPoint);
        obj = [NSValue value:&actual withObjCType:type];
    } else if (strcmp(type, @encode(CGSize)) == 0) {
        CGSize actual = (CGSize)va_arg(v, CGSize);
        obj = [NSValue value:&actual withObjCType:type];
    } else if (strcmp(type, @encode(MASEdgeInsets)) == 0) {
        MASEdgeInsets actual = (MASEdgeInsets)va_arg(v, MASEdgeInsets);
        obj = [NSValue value:&actual withObjCType:type];
    } else if (strcmp(type, @encode(double)) == 0) {
        double actual = (double)va_arg(v, double);
        obj = [NSNumber numberWithDouble:actual];
    } else if (strcmp(type, @encode(float)) == 0) {
        float actual = (float)va_arg(v, double);
        obj = [NSNumber numberWithFloat:actual];
    } else if (strcmp(type, @encode(int)) == 0) {
        int actual = (int)va_arg(v, int);
        obj = [NSNumber numberWithInt:actual];
    } else if (strcmp(type, @encode(long)) == 0) {
        long actual = (long)va_arg(v, long);
        obj = [NSNumber numberWithLong:actual];
    } else if (strcmp(type, @encode(long long)) == 0) {
        long long actual = (long long)va_arg(v, long long);
        obj = [NSNumber numberWithLongLong:actual];
    } else if (strcmp(type, @encode(short)) == 0) {
        short actual = (short)va_arg(v, int);
        obj = [NSNumber numberWithShort:actual];
    } else if (strcmp(type, @encode(char)) == 0) {
        char actual = (char)va_arg(v, int);
        obj = [NSNumber numberWithChar:actual];
    } else if (strcmp(type, @encode(bool)) == 0) {
        bool actual = (bool)va_arg(v, int);
        obj = [NSNumber numberWithBool:actual];
    } else if (strcmp(type, @encode(unsigned char)) == 0) {
        unsigned char actual = (unsigned char)va_arg(v, unsigned int);
        obj = [NSNumber numberWithUnsignedChar:actual];
    } else if (strcmp(type, @encode(unsigned int)) == 0) {
        unsigned int actual = (unsigned int)va_arg(v, unsigned int);
        obj = [NSNumber numberWithUnsignedInt:actual];
    } else if (strcmp(type, @encode(unsigned long)) == 0) {
        unsigned long actual = (unsigned long)va_arg(v, unsigned long);
        obj = [NSNumber numberWithUnsignedLong:actual];
    } else if (strcmp(type, @encode(unsigned long long)) == 0) {
        unsigned long long actual = (unsigned long long)va_arg(v, unsigned long long);
        obj = [NSNumber numberWithUnsignedLongLong:actual];
    } else if (strcmp(type, @encode(unsigned short)) == 0) {
        unsigned short actual = (unsigned short)va_arg(v, unsigned int);
        obj = [NSNumber numberWithUnsignedShort:actual];
    }
    va_end(v);
    return obj;
}

#define MASBoxValue(value) _MASBoxValue(@encode(__typeof__((value))), (value))


================================================
FILE: KJBannerViewDemo/Masonry/MASViewAttribute.h
================================================
//
//  MASViewAttribute.h
//  Masonry
//
//  Created by Jonas Budelmann on 21/07/13.
//  Copyright (c) 2013 cloudling. All rights reserved.
//

#import "MASUtilities.h"

/**
 *  An immutable tuple which stores the view and the related NSLayoutAttribute.
 *  Describes part of either the left or right hand side of a constraint equation
 */
@interface MASViewAttribute : NSObject

/**
 *  The view which the reciever relates to. Can be nil if item is not a view.
 */
@property (nonatomic, weak, readonly) MAS_VIEW *view;

/**
 *  The item which the reciever relates to.
 */
@property (nonatomic, weak, readonly) id item;

/**
 *  The attribute which the reciever relates to
 */
@property (nonatomic, assign, readonly) NSLayoutAttribute layoutAttribute;

/**
 *  Convenience initializer.
 */
- (id)initWithView:(MAS_VIEW *)view layoutAttribute:(NSLayoutAttribute)layoutAttribute;

/**
 *  The designated initializer.
 */
- (id)initWithView:(MAS_VIEW *)view item:(id)item layoutAttribute:(NSLayoutAttribute)layoutAttribute;

/**
 *	Determine whether the layoutAttribute is a size attribute
 *
 *	@return	YES if layoutAttribute is equal to NSLayoutAttributeWidth or NSLayoutAttributeHeight
 */
- (BOOL)isSizeAttribute;

@end


================================================
FILE: KJBannerViewDemo/Masonry/MASViewAttribute.m
================================================
//
//  MASViewAttribute.m
//  Masonry
//
//  Created by Jonas Budelmann on 21/07/13.
//  Copyright (c) 2013 cloudling. All rights reserved.
//

#import "MASViewAttribute.h"

@implementation MASViewAttribute

- (id)initWithView:(MAS_VIEW *)view layoutAttribute:(NSLayoutAttribute)layoutAttribute {
    self = [self initWithView:view item:view layoutAttribute:layoutAttribute];
    return self;
}

- (id)initWithView:(MAS_VIEW *)view item:(id)item layoutAttribute:(NSLayoutAttribute)layoutAttribute {
    self = [super init];
    if (!self) return nil;
    
    _view = view;
    _item = item;
    _layoutAttribute = layoutAttribute;
    
    return self;
}

- (BOOL)isSizeAttribute {
    return self.layoutAttribute == NSLayoutAttributeWidth
        || self.layoutAttribute == NSLayoutAttributeHeight;
}

- (BOOL)isEqual:(MASViewAttribute *)viewAttribute {
    if ([viewAttribute isKindOfClass:self.class]) {
        return self.view == viewAttribute.view
            && self.layoutAttribute == viewAttribute.layoutAttribute;
    }
    return [super isEqual:viewAttribute];
}

- (NSUInteger)hash {
    return MAS_NSUINTROTATE([self.view hash], MAS_NSUINT_BIT / 2) ^ self.layoutAttribute;
}

@end


================================================
FILE: KJBannerViewDemo/Masonry/MASViewConstraint.h
================================================
//
//  MASViewConstraint.h
//  Masonry
//
//  Created by Jonas Budelmann on 20/07/13.
//  Copyright (c) 2013 cloudling. All rights reserved.
//

#import "MASViewAttribute.h"
#import "MASConstraint.h"
#import "MASLayoutConstraint.h"
#import "MASUtilities.h"

/**
 *  A single constraint.
 *  Contains the attributes neccessary for creating a NSLayoutConstraint and adding it to the appropriate view
 */
@interface MASViewConstraint : MASConstraint <NSCopying>

/**
 *	First item/view and first attribute of the NSLayoutConstraint
 */
@property (nonatomic, strong, readonly) MASViewAttribute *firstViewAttribute;

/**
 *	Second item/view and second attribute of the NSLayoutConstraint
 */
@property (nonatomic, strong, readonly) MASViewAttribute *secondViewAttribute;

/**
 *	initialises the MASViewConstraint with the first part of the equation
 *
 *	@param	firstViewAttribute	view.mas_left, view.mas_width etc.
 *
 *	@return	a new view constraint
 */
- (id)initWithFirstViewAttribute:(MASViewAttribute *)firstViewAttribute;

/**
 *  Returns all MASViewConstraints installed with this view as a first item.
 *
 *  @param  view  A view to retrieve constraints for.
 *
 *  @return An array of MASViewConstraints.
 */
+ (NSArray *)installedConstraintsForView:(MAS_VIEW *)view;

@end


================================================
FILE: KJBannerViewDemo/Masonry/MASViewConstraint.m
================================================
//
//  MASViewConstraint.m
//  Masonry
//
//  Created by Jonas Budelmann on 20/07/13.
//  Copyright (c) 2013 cloudling. All rights reserved.
//

#import "MASViewConstraint.h"
#import "MASConstraint+Private.h"
#import "MASCompositeConstraint.h"
#import "MASLayoutConstraint.h"
#import "View+MASAdditions.h"
#import <objc/runtime.h>

@interface MAS_VIEW (MASConstraints)

@property (nonatomic, readonly) NSMutableSet *mas_installedConstraints;

@end

@implementation MAS_VIEW (MASConstraints)

static char kInstalledConstraintsKey;

- (NSMutableSet *)mas_installedConstraints {
    NSMutableSet *constraints = objc_getAssociatedObject(self, &kInstalledConstraintsKey);
    if (!constraints) {
        constraints = [NSMutableSet set];
        objc_setAssociatedObject(self, &kInstalledConstraintsKey, constraints, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    return constraints;
}

@end


@interface MASViewConstraint ()

@property (nonatomic, strong, readwrite) MASViewAttribute *secondViewAttribute;
@property (nonatomic, weak) MAS_VIEW *installedView;
@property (nonatomic, weak) MASLayoutConstraint *layoutConstraint;
@property (nonatomic, assign) NSLayoutRelation layoutRelation;
@property (nonatomic, assign) MASLayoutPriority layoutPriority;
@property (nonatomic, assign) CGFloat layoutMultiplier;
@property (nonatomic, assign) CGFloat layoutConstant;
@property (nonatomic, assign) BOOL hasLayoutRelation;
@property (nonatomic, strong) id mas_key;
@property (nonatomic, assign) BOOL useAnimator;

@end

@implementation MASViewConstraint

- (id)initWithFirstViewAttribute:(MASViewAttribute *)firstViewAttribute {
    self = [super init];
    if (!self) return nil;
    
    _firstViewAttribute = firstViewAttribute;
    self.layoutPriority = MASLayoutPriorityRequired;
    self.layoutMultiplier = 1;
    
    return self;
}

#pragma mark - NSCoping

- (id)copyWithZone:(NSZone __unused *)zone {
    MASViewConstraint *constraint = [[MASViewConstraint alloc] initWithFirstViewAttribute:self.firstViewAttribute];
    constraint.layoutConstant = self.layoutConstant;
    constraint.layoutRelation = self.layoutRelation;
    constraint.layoutPriority = self.layoutPriority;
    constraint.layoutMultiplier = self.layoutMultiplier;
    constraint.delegate = self.delegate;
    return constraint;
}

#pragma mark - Public

+ (NSArray *)installedConstraintsForView:(MAS_VIEW *)view {
    return [view.mas_installedConstraints allObjects];
}

#pragma mark - Private

- (void)setLayoutConstant:(CGFloat)layoutConstant {
    _layoutConstant = layoutConstant;

#if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV)
    if (self.useAnimator) {
        [self.layoutConstraint.animator setConstant:layoutConstant];
    } else {
        self.layoutConstraint.constant = layoutConstant;
    }
#else
    self.layoutConstraint.constant = layoutConstant;
#endif
}

- (void)setLayoutRelation:(NSLayoutRelation)layoutRelation {
    _layoutRelation = layoutRelation;
    self.hasLayoutRelation = YES;
}

- (BOOL)supportsActiveProperty {
    return [self.layoutConstraint respondsToSelector:@selector(isActive)];
}

- (BOOL)isActive {
    BOOL active = YES;
    if ([self supportsActiveProperty]) {
        active = [self.layoutConstraint isActive];
    }

    return active;
}

- (BOOL)hasBeenInstalled {
    return (self.layoutConstraint != nil) && [self isActive];
}

- (void)setSecondViewAttribute:(id)secondViewAttribute {
    if ([secondViewAttribute isKindOfClass:NSValue.class]) {
        [self setLayoutConstantWithValue:secondViewAttribute];
    } else if ([secondViewAttribute isKindOfClass:MAS_VIEW.class]) {
        _secondViewAttribute = [[MASViewAttribute alloc] initWithView:secondViewAttribute layoutAttribute:self.firstViewAttribute.layoutAttribute];
    } else if ([secondViewAttribute isKindOfClass:MASViewAttribute.class]) {
        _secondViewAttribute = secondViewAttribute;
    } else {
        NSAssert(NO, @"attempting to add unsupported attribute: %@", secondViewAttribute);
    }
}

#pragma mark - NSLayoutConstraint multiplier proxies

- (MASConstraint * (^)(CGFloat))multipliedBy {
    return ^id(CGFloat multiplier) {
        NSAssert(!self.hasBeenInstalled,
                 @"Cannot modify constraint multiplier after it has been installed");
        
        self.layoutMultiplier = multiplier;
        return self;
    };
}


- (MASConstraint * (^)(CGFloat))dividedBy {
    return ^id(CGFloat divider) {
        NSAssert(!self.hasBeenInstalled,
                 @"Cannot modify constraint multiplier after it has been installed");

        self.layoutMultiplier = 1.0/divider;
        return self;
    };
}

#pragma mark - MASLayoutPriority proxy

- (MASConstraint * (^)(MASLayoutPriority))priority {
    return ^id(MASLayoutPriority priority) {
        NSAssert(!self.hasBeenInstalled,
                 @"Cannot modify constraint priority after it has been installed");
        
        self.layoutPriority = priority;
        return self;
    };
}

#pragma mark - NSLayoutRelation proxy

- (MASConstraint * (^)(id, NSLayoutRelation))equalToWithRelation {
    return ^id(id attribute, NSLayoutRelation relation) {
        if ([attribute isKindOfClass:NSArray.class]) {
            NSAssert(!self.hasLayoutRelation, @"Redefinition of constraint relation");
            NSMutableArray *children = NSMutableArray.new;
            for (id attr in attribute) {
                MASViewConstraint *viewConstraint = [self copy];
                viewConstraint.layoutRelation = relation;
                viewConstraint.secondViewAttribute = attr;
                [children addObject:viewConstraint];
            }
            MASCompositeConstraint *compositeConstraint = [[MASCompositeConstraint alloc] initWithChildren:children];
            compositeConstraint.delegate = self.delegate;
            [self.delegate constraint:self shouldBeReplacedWithConstraint:compositeConstraint];
            return compositeConstraint;
        } else {
            NSAssert(!self.hasLayoutRelation || self.layoutRelation == relation && [attribute isKindOfClass:NSValue.class], @"Redefinition of constraint relation");
            self.layoutRelation = relation;
            self.secondViewAttribute = attribute;
            return self;
        }
    };
}

#pragma mark - Semantic properties

- (MASConstraint *)with {
    return self;
}

- (MASConstraint *)and {
    return self;
}

#pragma mark - attribute chaining

- (MASConstraint *)addConstraintWithLayoutAttribute:(NSLayoutAttribute)layoutAttribute {
    NSAssert(!self.hasLayoutRelation, @"Attributes should be chained before defining the constraint relation");

    return [self.delegate constraint:self addConstraintWithLayoutAttribute:layoutAttribute];
}

#pragma mark - Animator proxy

#if TARGET_OS_MAC && !(TARGET_OS_IPHONE || TARGET_OS_TV)

- (MASConstraint *)animator {
    self.useAnimator = YES;
    return self;
}

#endif

#pragma mark - debug helpers

- (MASConstraint * (^)(id))key {
    return ^id(id key) {
        self.mas_key = key;
        return self;
    };
}

#pragma mark - NSLayoutConstraint constant setters

- (void)setInsets:(MASEdgeInsets)insets {
    NSLayoutAttribute layoutAttribute = self.firstViewAttribute.layoutAttribute;
    switch (layoutAttribute) {
        case NSLayoutAttributeLeft:
        case NSLayoutAttributeLeading:
            self.layoutConstant = insets.left;
            break;
        case NSLayoutAttributeTop:
            self.layoutConstant = insets.top;
            break;
        case NSLayoutAttributeBottom:
            self.layoutConstant = -insets.bottom;
            break;
        case NSLayoutAttributeRight:
        case NSLayoutAttributeTrailing:
            self.layoutConstant = -insets.right;
            break;
        default:
            break;
    }
}

- (void)setInset:(CGFloat)inset {
    [self setInsets:(MASEdgeInsets){.top = inset, .left = inset, .bottom = inset, .right = inset}];
}

- (void)setOffset:(CGFloat)offset {
    self.layoutConstant = offset;
}

- (void)setSizeOffset:(CGSize)sizeOffset {
    NSLayoutAttribute layoutAttribute = self.firstViewAttribute.layoutAttribute;
    switch (layoutAttribute) {
        case NSLayoutAttributeWidth:
            self.layoutConstant = sizeOffset.width;
            break;
        case NSLayoutAttributeHeight:
            self.layoutConstant = sizeOffset.height;
            break;
        default:
            break;
    }
}

- (void)setCenterOffset:(CGPoint)centerOffset {
    NSLayoutAttribute layoutAttribute = self.firstViewAttribute.layoutAttribute;
    switch (layoutAttribute) {
        case NSLayoutAttributeCenterX:
            self.layoutConstant = centerOffset.x;
            break;
        case NSLayoutAttributeCenterY:
            self.layoutConstant = centerOffset.y;
            break;
        default:
            break;
    }
}

#pragma mark - MASConstraint

- (void)activate {
    [self install];
}

- (void)deactivate {
    [self uninstall];
}

- (void)install {
    if (self.hasBeenInstalled) {
        return;
    }
    
    if ([self supportsActiveProperty] && self.layoutConstraint) {
        self.layoutConstraint.active = YES;
        [self.firstViewAttribute.view.mas_installedConstraints addObject:self];
        return;
    }
    
    MAS_VIEW *firstLayoutItem = self.firstViewAttribute.item;
    NSLayoutAttribute firstLayoutAttribute = self.firstViewAttribute.layoutAttribute;
    MAS_VIEW *secondLayoutItem = self.secondViewAttribute.item;
    NSLayoutAttribute secondLayoutAttribute = self.secondViewAttribute.layoutAttribute;

    // alignment attributes must have a secondViewAttribute
    // therefore we assume that is refering to superview
    // eg make.left.equalTo(@10)
    if (!self.firstViewAttribute.isSizeAttribute && !self.secondViewAttribute) {
        secondLayoutItem = self.firstViewAttribute.view.superview;
        secondLayoutAttribute = firstLayoutAttribute;
    }
    
    MASLayoutConstraint *layoutConstraint
        = [MASLayoutConstraint constraintWithItem:firstLayoutItem
                                        attribute:firstLayoutAttribute
                                        relatedBy:self.layoutRelation
                                           toItem:secondLayoutItem
                                        attribute:secondLayoutAttribute
                                       multiplier:self.layoutMultiplier
                                         constant:self.layoutConstant];
    
    layoutConstraint.priority = self.layoutPriority;
    layoutConstraint.mas_key = self.mas_key;
    
    if (self.secondViewAttribute.view) {
        MAS_VIEW *closestCommonSuperview = [self.firstViewAttribute.view mas_closestCommonSuperview:self.secondViewAttribute.view];
        NSAssert(closestCommonSuperview,
                 @"couldn't find a common superview for %@ and %@",
                 self.firstViewAttribute.view, self.secondViewAttribute.view);
        self.installedView = closestCommonSuperview;
    } else if (self.firstViewAttribute.isSizeAttribute) {
        self.installedView = self.firstViewAttribute.view;
    } else {
        self.installedView = self.firstViewAttribute.view.superview;
    }


    MASLayoutConstraint *existingConstraint = nil;
    if (self.updateExisting) {
        existingConstraint = [self layoutConstraintSimilarTo:layoutConstraint];
    }
    if (existingConstraint) {
        // just update the constant
        existingConstraint.constant = layoutConstraint.constant;
        self.layoutConstraint = existingConstraint;
    } else {
        [self.installedView addConstraint:layoutConstraint];
        self.layoutConstraint = layoutConstraint;
        [firstLayoutItem.mas_installedConstraints addObject:self];
    }
}

- (MASLayoutConstraint *)layoutConstraintSimilarTo:(MASLayoutConstraint *)layoutConstraint {
    // check if any constraints are the same apart from the only mutable property constant

    // go through constraints in reverse as we do not want to match auto-resizing or interface builder constraints
    // and they are likely to be added first.
    for (NSLayoutConstraint *existingConstraint in self.installedView.constraints.reverseObjectEnumerator) {
        if (![existingConstraint isKindOfClass:MASLayoutConstraint.class]) continue;
        if (existingConstraint.firstItem != layoutConstraint.firstItem) continue;
        if (existingConstraint.secondItem != layoutConstraint.secondItem) continue;
        if (existingConstraint.firstAttribute != layoutConstraint.firstAttribute) continue;
        if (existingConstraint.secondAttribute != layoutConstraint.secondAttribute) continue;
        if (existingConstraint.relation != layoutConstraint.relation) continue;
        if (existingConstraint.multiplier != layoutConstraint.multiplier) continue;
        if (existingConstraint.priority != layoutConstraint.priority) continue;

        return (id)existingConstraint;
    }
    return nil;
}

- (void)uninstall {
    if ([self supportsActiveProperty]) {
        self.layoutConstraint.active = NO;
        [self.firstViewAttribute.view.mas_installedConstraints removeObject:self];
        return;
    }
    
    [self.installedView removeConstraint:self.layoutConstraint];
    self.layoutConstraint = nil;
    self.installedView = nil;
    
    [self.firstViewAttribute.view.mas_installedConstraints removeObject:self];
}

@end


================================================
FILE: KJBannerViewDemo/Masonry/Masonry.h
================================================
//
//  Masonry.h
//  Masonry
//
//  Created by Jonas Budelmann on 20/07/13.
//  Copyright (c) 2013 cloudling. All rights reserved.
//

#import <Foundation/Foundation.h>

//! Project version number for Masonry.
FOUNDATION_EXPORT double MasonryVersionNumber;

//! Project version string for Masonry.
FOUNDATION_EXPORT const unsigned char MasonryVersionString[];

#import "MASUtilities.h"
#import "View+MASAdditions.h"
#import "View+MASShorthandAdditions.h"
#import "ViewController+MASAdditions.h"
#import "NSArray+MASAdditions.h"
#import "NSArray+MASShorthandAdditions.h"
#import "MASConstraint.h"
#import "MASCompositeConstraint.h"
#import "MASViewAttribute.h"
#import "MASViewConstraint.h"
#import "MASConstraintMaker.h"
#import "MASLayoutConstraint.h"
#import "NSLayoutConstraint+MASDebugAdditions.h"


================================================
FILE: KJBannerViewDemo/Masonry/NSArray+MASAdditions.h
================================================
//
//  NSArray+MASAdditions.h
//
//
//  Created by Daniel Hammond on 11/26/13.
//
//

#import "MASUtilities.h"
#import "MASConstraintMaker.h"
#import "MASViewAttribute.h"

typedef NS_ENUM(NSUInteger, MASAxisType) {
    MASAxisTypeHorizontal,
    MASAxisTypeVertical
};

@interface NSArray (MASAdditions)

/**
 *  Creates a MASConstraintMaker with each view in the callee.
 *  Any constraints defined are added to the view or the appropriate superview once the block has finished executing on each view
 *
 *  @param block scope within which you can build up the constraints which you wish to apply to each view.
 *
 *  @return Array of created MASConstraints
 */
- (NSArray *)mas_makeConstraints:(void (NS_NOESCAPE ^)(MASConstraintMaker *make))block;

/**
 *  Creates a MASConstraintMaker with each view in the callee.
 *  Any constraints defined are added to each view or the appropriate superview once the block has finished executing on each view.
 *  If an existing constraint exists then it will be updated instead.
 *
 *  @param block scope within which you can build up the constraints which you wish to apply to each view.
 *
 *  @return Array of created/updated MASConstraints
 */
- (NSArray *)mas_updateConstraints:(void (NS_NOESCAPE ^)(MASConstraintMaker *make))block;

/**
 *  Creates a MASConstraintMaker with each view in the callee.
 *  Any constraints defined are added to each view or the appropriate superview once the block has finished executing on each view.
 *  All constraints previously installed for the views will be removed.
 *
 *  @param block scope within which you can build up the constraints which you wish to apply to each view.
 *
 *  @return Array of created/updated MASConstraints
 */
- (NSArray *)mas_remakeConstraints:(void (NS_NOESCAPE ^)(MASConstraintMaker *make))block;

/**
 *  distribute with fixed spacing
 *
 *  @param axisType     which axis to distribute items along
 *  @param fixedSpacing the spacing between each item
 *  @param leadSpacing  the spacing before the first item and the container
 *  @param tailSpacing  the spacing after the last item and the container
 */
- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)fixedSpacing leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing;

/**
 *  distribute with fixed item size
 *
 *  @param axisType        which axis to distribute items along
 *  @param fixedItemLength the fixed length of each item
 *  @param leadSpacing     the spacing before the first item and the container
 *  @param tailSpacing     the spacing after the last item and the container
 */
- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)fixedItemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing;

@end


================================================
FILE: KJBannerViewDemo/Masonry/NSArray+MASAdditions.m
================================================
//
//  NSArray+MASAdditions.m
//  
//
//  Created by Daniel Hammond on 11/26/13.
//
//

#import "NSArray+MASAdditions.h"
#import "View+MASAdditions.h"

@implementation NSArray (MASAdditions)

- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *make))block {
    NSMutableArray *constraints = [NSMutableArray array];
    for (MAS_VIEW *view in self) {
        NSAssert([view isKindOfClass:[MAS_VIEW class]], @"All objects in the array must be views");
        [constraints addObjectsFromArray:[view mas_makeConstraints:block]];
    }
    return constraints;
}

- (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *make))block {
    NSMutableArray *constraints = [NSMutableArray array];
    for (MAS_VIEW *view in self) {
        NSAssert([view isKindOfClass:[MAS_VIEW class]], @"All objects in the array must be views");
        [constraints addObjectsFromArray:[view mas_updateConstraints:block]];
    }
    return constraints;
}

- (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block {
    NSMutableArray *constraints = [NSMutableArray array];
    for (MAS_VIEW *view in self) {
        NSAssert([view isKindOfClass:[MAS_VIEW class]], @"All objects in the array must be views");
        [constraints addObjectsFromArray:[view mas_remakeConstraints:block]];
    }
    return constraints;
}

- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedSpacing:(CGFloat)fixedSpacing leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing {
    if (self.count < 2) {
        NSAssert(self.count>1,@"views to distribute need to bigger than one");
        return;
    }
    
    MAS_VIEW *tempSuperView = [self mas_commonSuperviewOfViews];
    if (axisType == MASAxisTypeHorizontal) {
        MAS_VIEW *prev;
        for (int i = 0; i < self.count; i++) {
            MAS_VIEW *v = self[i];
            [v mas_makeConstraints:^(MASConstraintMaker *make) {
                if (prev) {
                    make.width.equalTo(prev);
                    make.left.equalTo(prev.mas_right).offset(fixedSpacing);
                    if (i == self.count - 1) {//last one
                        make.right.equalTo(tempSuperView).offset(-tailSpacing);
                    }
                }
                else {//first one
                    make.left.equalTo(tempSuperView).offset(leadSpacing);
                }
                
            }];
            prev = v;
        }
    }
    else {
        MAS_VIEW *prev;
        for (int i = 0; i < self.count; i++) {
            MAS_VIEW *v = self[i];
            [v mas_makeConstraints:^(MASConstraintMaker *make) {
                if (prev) {
                    make.height.equalTo(prev);
                    make.top.equalTo(prev.mas_bottom).offset(fixedSpacing);
                    if (i == self.count - 1) {//last one
                        make.bottom.equalTo(tempSuperView).offset(-tailSpacing);
                    }                    
                }
                else {//first one
                    make.top.equalTo(tempSuperView).offset(leadSpacing);
                }
                
            }];
            prev = v;
        }
    }
}

- (void)mas_distributeViewsAlongAxis:(MASAxisType)axisType withFixedItemLength:(CGFloat)fixedItemLength leadSpacing:(CGFloat)leadSpacing tailSpacing:(CGFloat)tailSpacing {
    if (self.count < 2) {
        NSAssert(self.count>1,@"views to distribute need to bigger than one");
        return;
    }
    
    MAS_VIEW *tempSuperView = [self mas_commonSuperviewOfViews];
    if (axisType == MASAxisTypeHorizontal) {
        MAS_VIEW *prev;
        for (int i = 0; i < self.count; i++) {
            MAS_VIEW *v = self[i];
            [v mas_makeConstraints:^(MASConstraintMaker *make) {
                make.width.equalTo(@(fixedItemLength));
                if (prev) {
                    if (i == self.count - 1) {//last one
                        make.right.equalTo(tempSuperView).offset(-tailSpacing);
                    }
                    else {
                        CGFloat offset = (1-(i/((CGFloat)self.count-1)))*(fixedItemLength+leadSpacing)-i*tailSpacing/(((CGFloat)self.count-1));
                        make.right.equalTo(tempSuperView).multipliedBy(i/((CGFloat)self.count-1)).with.offset(offset);
                    }
                }
                else {//first one
                    make.left.equalTo(tempSuperView).offset(leadSpacing);
                }
            }];
            prev = v;
        }
    }
    else {
        MAS_VIEW *prev;
        for (int i = 0; i < self.count; i++) {
            MAS_VIEW *v = self[i];
            [v mas_makeConstraints:^(MASConstraintMaker *make) {
                make.height.equalTo(@(fixedItemLength));
                if (prev) {
                    if (i == self.count - 1) {//last one
                        make.bottom.equalTo(tempSuperView).offset(-tailSpacing);
                    }
                    else {
                        CGFloat offset = (1-(i/((CGFloat)self.count-1)))*(fixedItemLength+leadSpacing)-i*tailSpacing/(((CGFloat)self.count-1));
                        make.bottom.equalTo(tempSuperView).multipliedBy(i/((CGFloat)self.count-1)).with.offset(offset);
                    }
                }
                else {//first one
                    make.top.equalTo(tempSuperView).offset(leadSpacing);
                }
            }];
            prev = v;
        }
    }
}

- (MAS_VIEW *)mas_commonSuperviewOfViews
{
    MAS_VIEW *commonSuperview = nil;
    MAS_VIEW *previousView = nil;
    for (id object in self) {
        if ([object isKindOfClass:[MAS_VIEW class]]) {
            MAS_VIEW *view = (MAS_VIEW *)object;
            if (previousView) {
                commonSuperview = [view mas_closestCommonSuperview:commonSuperview];
            } else {
                commonSuperview = view;
            }
            previousView = view;
        }
    }
    NSAssert(commonSuperview, @"Can't constrain views that do not share a common superview. Make sure that all the views in this array have been added into the same view hierarchy.");
    return commonSuperview;
}

@end


================================================
FILE: KJBannerViewDemo/Masonry/NSArray+MASShorthandAdditions.h
================================================
//
//  NSArray+MASShorthandAdditions.h
//  Masonry
//
//  Created by Jonas Budelmann on 22/07/13.
//  Copyright (c) 2013 Jonas Budelmann. All rights reserved.
//

#import "NSArray+MASAdditions.h"

#ifdef MAS_SHORTHAND

/**
 *	Shorthand array additions without the 'mas_' prefixes,
 *  only enabled if MAS_SHORTHAND is defined
 */
@interface NSArray (MASShorthandAdditions)

- (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *make))block;
- (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *make))block;
- (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *make))block;

@end

@implementation NSArray (MASShorthandAdditions)

- (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *))block {
    return [self mas_makeConstraints:block];
}

- (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *))block {
    return [self mas_updateConstraints:block];
}

- (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *))block {
    return [self mas_remakeConstraints:block];
}

@end

#endif


================================================
FILE: KJBannerViewDemo/Masonry/NSLayoutConstraint+MASDebugAdditions.h
================================================
//
//  NSLayoutConstraint+MASDebugAdditions.h
//  Masonry
//
//  Created by Jonas Budelmann on 3/08/13.
//  Copyright (c) 2013 Jonas Budelmann. All rights reserved.
//

#import "MASUtilities.h"

/**
 *	makes debug and log output of NSLayoutConstraints more readable
 */
@interface NSLayoutConstraint (MASDebugAdditions)

@end


================================================
FILE: KJBannerViewDemo/Masonry/NSLayoutConstraint+MASDebugAdditions.m
================================================
//
//  NSLayoutConstraint+MASDebugAdditions.m
//  Masonry
//
//  Created by Jonas Budelmann on 3/08/13.
//  Copyright (c) 2013 Jonas Budelmann. All rights reserved.
//

#import "NSLayoutConstraint+MASDebugAdditions.h"
#import "MASConstraint.h"
#import "MASLayoutConstraint.h"

@implementation NSLayoutConstraint (MASDebugAdditions)

#pragma mark - description maps

+ (NSDictionary *)layoutRelationDescriptionsByValue {
    static dispatch_once_t once;
    static NSDictionary *descriptionMap;
    dispatch_once(&once, ^{
        descriptionMap = @{
            @(NSLayoutRelationEqual)                : @"==",
            @(NSLayoutRelationGreaterThanOrEqual)   : @">=",
            @(NSLayoutRelationLessThanOrEqual)      : @"<=",
        };
    });
    return descriptionMap;
}

+ (NSDictionary *)layoutAttributeDescriptionsByValue {
    static dispatch_once_t once;
    static NSDictionary *descriptionMap;
    dispatch_once(&once, ^{
        descriptionMap = @{
            @(NSLayoutAttributeTop)      : @"top",
            @(NSLayoutAttributeLeft)     : @"left",
            @(NSLayoutAttributeBottom)   : @"bottom",
            @(NSLayoutAttributeRight)    : @"right",
            @(NSLayoutAttributeLeading)  : @"leading",
            @(NSLayoutAttributeTrailing) : @"trailing",
            @(NSLayoutAttributeWidth)    : @"width",
            @(NSLayoutAttributeHeight)   : @"height",
            @(NSLayoutAttributeCenterX)  : @"centerX",
            @(NSLayoutAttributeCenterY)  : @"centerY",
            @(NSLayoutAttributeBaseline) : @"baseline",
            
#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100)
            @(NSLayoutAttributeFirstBaseline) : @"firstBaseline",
            @(NSLayoutAttributeLastBaseline) : @"lastBaseline",
#endif
            
#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000)
            @(NSLayoutAttributeLeftMargin)           : @"leftMargin",
            @(NSLayoutAttributeRightMargin)          : @"rightMargin",
            @(NSLayoutAttributeTopMargin)            : @"topMargin",
            @(NSLayoutAttributeBottomMargin)         : @"bottomMargin",
            @(NSLayoutAttributeLeadingMargin)        : @"leadingMargin",
            @(NSLayoutAttributeTrailingMargin)       : @"trailingMargin",
            @(NSLayoutAttributeCenterXWithinMargins) : @"centerXWithinMargins",
            @(NSLayoutAttributeCenterYWithinMargins) : @"centerYWithinMargins",
#endif
            
        };
    
    });
    return descriptionMap;
}


+ (NSDictionary *)layoutPriorityDescriptionsByValue {
    static dispatch_once_t once;
    static NSDictionary *descriptionMap;
    dispatch_once(&once, ^{
#if TARGET_OS_IPHONE || TARGET_OS_TV
        descriptionMap = @{
            @(MASLayoutPriorityDefaultHigh)      : @"high",
            @(MASLayoutPriorityDefaultLow)       : @"low",
            @(MASLayoutPriorityDefaultMedium)    : @"medium",
            @(MASLayoutPriorityRequired)         : @"required",
            @(MASLayoutPriorityFittingSizeLevel) : @"fitting size",
        };
#elif TARGET_OS_MAC
        descriptionMap = @{
            @(MASLayoutPriorityDefaultHigh)                 : @"high",
            @(MASLayoutPriorityDragThatCanResizeWindow)     : @"drag can resize window",
            @(MASLayoutPriorityDefaultMedium)               : @"medium",
            @(MASLayoutPriorityWindowSizeStayPut)           : @"window size stay put",
            @(MASLayoutPriorityDragThatCannotResizeWindow)  : @"drag cannot resize window",
            @(MASLayoutPriorityDefaultLow)                  : @"low",
            @(MASLayoutPriorityFittingSizeCompression)      : @"fitting size",
            @(MASLayoutPriorityRequired)                    : @"required",
        };
#endif
    });
    return descriptionMap;
}

#pragma mark - description override

+ (NSString *)descriptionForObject:(id)obj {
    if ([obj respondsToSelector:@selector(mas_key)] && [obj mas_key]) {
        return [NSString stringWithFormat:@"%@:%@", [obj class], [obj mas_key]];
    }
    return [NSString stringWithFormat:@"%@:%p", [obj class], obj];
}

- (NSString *)description {
    NSMutableString *description = [[NSMutableString alloc] initWithString:@"<"];

    [description appendString:[self.class descriptionForObject:self]];

    [description appendFormat:@" %@", [self.class descriptionForObject:self.firstItem]];
    if (self.firstAttribute != NSLayoutAttributeNotAnAttribute) {
        [description appendFormat:@".%@", self.class.layoutAttributeDescriptionsByValue[@(self.firstAttribute)]];
    }

    [description appendFormat:@" %@", self.class.layoutRelationDescriptionsByValue[@(self.relation)]];

    if (self.secondItem) {
        [description appendFormat:@" %@", [self.class descriptionForObject:self.secondItem]];
    }
    if (self.secondAttribute != NSLayoutAttributeNotAnAttribute) {
        [description appendFormat:@".%@", self.class.layoutAttributeDescriptionsByValue[@(self.secondAttribute)]];
    }
    
    if (self.multiplier != 1) {
        [description appendFormat:@" * %g", self.multiplier];
    }
    
    if (self.secondAttribute == NSLayoutAttributeNotAnAttribute) {
        [description appendFormat:@" %g", self.constant];
    } else {
        if (self.constant) {
            [description appendFormat:@" %@ %g", (self.constant < 0 ? @"-" : @"+"), ABS(self.constant)];
        }
    }

    if (self.priority != MASLayoutPriorityRequired) {
        [description appendFormat:@" ^%@", self.class.layoutPriorityDescriptionsByValue[@(self.priority)] ?: [NSNumber numberWithDouble:self.priority]];
    }

    [description appendString:@">"];
    return description;
}

@end


================================================
FILE: KJBannerViewDemo/Masonry/View+MASAdditions.h
================================================
//
//  UIView+MASAdditions.h
//  Masonry
//
//  Created by Jonas Budelmann on 20/07/13.
//  Copyright (c) 2013 cloudling. All rights reserved.
//

#import "MASUtilities.h"
#import "MASConstraintMaker.h"
#import "MASViewAttribute.h"

/**
 *	Provides constraint maker block
 *  and convience methods for creating MASViewAttribute which are view + NSLayoutAttribute pairs
 */
@interface MAS_VIEW (MASAdditions)

/**
 *	following properties return a new MASViewAttribute with current view and appropriate NSLayoutAttribute
 */
@property (nonatomic, strong, readonly) MASViewAttribute *mas_left;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_top;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_right;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_bottom;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_leading;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_trailing;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_width;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_height;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_centerX;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_centerY;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_baseline;
@property (nonatomic, strong, readonly) MASViewAttribute *(^mas_attribute)(NSLayoutAttribute attr);

#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100)

@property (nonatomic, strong, readonly) MASViewAttribute *mas_firstBaseline;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_lastBaseline;

#endif

#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000)

@property (nonatomic, strong, readonly) MASViewAttribute *mas_leftMargin;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_rightMargin;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_topMargin;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomMargin;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_leadingMargin;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_trailingMargin;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_centerXWithinMargins;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_centerYWithinMargins;

#endif

#if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 110000) || (__TV_OS_VERSION_MAX_ALLOWED >= 110000)

@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuide API_AVAILABLE(ios(11.0),tvos(11.0));
@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideTop API_AVAILABLE(ios(11.0),tvos(11.0));
@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideBottom API_AVAILABLE(ios(11.0),tvos(11.0));
@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideLeft API_AVAILABLE(ios(11.0),tvos(11.0));
@property (nonatomic, strong, readonly) MASViewAttribute *mas_safeAreaLayoutGuideRight API_AVAILABLE(ios(11.0),tvos(11.0));

#endif

/**
 *	a key to associate with this view
 */
@property (nonatomic, strong) id mas_key;

/**
 *	Finds the closest common superview between this view and another view
 *
 *	@param	view	other view
 *
 *	@return	returns nil if common superview could not be found
 */
- (instancetype)mas_closestCommonSuperview:(MAS_VIEW *)view;

/**
 *  Creates a MASConstraintMaker with the callee view.
 *  Any constraints defined are added to the view or the appropriate superview once the block has finished executing
 *
 *  @param block scope within which you can build up the constraints which you wish to apply to the view.
 *
 *  @return Array of created MASConstraints
 */
- (NSArray *)mas_makeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;

/**
 *  Creates a MASConstraintMaker with the callee view.
 *  Any constraints defined are added to the view or the appropriate superview once the block has finished executing.
 *  If an existing constraint exists then it will be updated instead.
 *
 *  @param block scope within which you can build up the constraints which you wish to apply to the view.
 *
 *  @return Array of created/updated MASConstraints
 */
- (NSArray *)mas_updateConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;

/**
 *  Creates a MASConstraintMaker with the callee view.
 *  Any constraints defined are added to the view or the appropriate superview once the block has finished executing.
 *  All constraints previously installed for the view will be removed.
 *
 *  @param block scope within which you can build up the constraints which you wish to apply to the view.
 *
 *  @return Array of created/updated MASConstraints
 */
- (NSArray *)mas_remakeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *make))block;

@end


================================================
FILE: KJBannerViewDemo/Masonry/View+MASAdditions.m
================================================
//
//  UIView+MASAdditions.m
//  Masonry
//
//  Created by Jonas Budelmann on 20/07/13.
//  Copyright (c) 2013 cloudling. All rights reserved.
//

#import "View+MASAdditions.h"
#import <objc/runtime.h>

@implementation MAS_VIEW (MASAdditions)

- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *))block {
    self.translatesAutoresizingMaskIntoConstraints = NO;
    MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self];
    block(constraintMaker);
    return [constraintMaker install];
}

- (NSArray *)mas_updateConstraints:(void(^)(MASConstraintMaker *))block {
    self.translatesAutoresizingMaskIntoConstraints = NO;
    MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self];
    constraintMaker.updateExisting = YES;
    block(constraintMaker);
    return [constraintMaker install];
}

- (NSArray *)mas_remakeConstraints:(void(^)(MASConstraintMaker *make))block {
    self.translatesAutoresizingMaskIntoConstraints = NO;
    MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self];
    constraintMaker.removeExisting = YES;
    block(constraintMaker);
    return [constraintMaker install];
}

#pragma mark - NSLayoutAttribute properties

- (MASViewAttribute *)mas_left {
    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeft];
}

- (MASViewAttribute *)mas_top {
    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTop];
}

- (MASViewAttribute *)mas_right {
    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeRight];
}

- (MASViewAttribute *)mas_bottom {
    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeBottom];
}

- (MASViewAttribute *)mas_leading {
    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeading];
}

- (MASViewAttribute *)mas_trailing {
    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTrailing];
}

- (MASViewAttribute *)mas_width {
    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeWidth];
}

- (MASViewAttribute *)mas_height {
    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeHeight];
}

- (MASViewAttribute *)mas_centerX {
    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterX];
}

- (MASViewAttribute *)mas_centerY {
    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterY];
}

- (MASViewAttribute *)mas_baseline {
    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeBaseline];
}

- (MASViewAttribute *(^)(NSLayoutAttribute))mas_attribute
{
    return ^(NSLayoutAttribute attr) {
        return [[MASViewAttribute alloc] initWithView:self layoutAttribute:attr];
    };
}

#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100)

- (MASViewAttribute *)mas_firstBaseline {
    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeFirstBaseline];
}
- (MASViewAttribute *)mas_lastBaseline {
    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLastBaseline];
}

#endif

#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000)

- (MASViewAttribute *)mas_leftMargin {
    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeftMargin];
}

- (MASViewAttribute *)mas_rightMargin {
    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeRightMargin];
}

- (MASViewAttribute *)mas_topMargin {
    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTopMargin];
}

- (MASViewAttribute *)mas_bottomMargin {
    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeBottomMargin];
}

- (MASViewAttribute *)mas_leadingMargin {
    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeLeadingMargin];
}

- (MASViewAttribute *)mas_trailingMargin {
    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeTrailingMargin];
}

- (MASViewAttribute *)mas_centerXWithinMargins {
    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterXWithinMargins];
}

- (MASViewAttribute *)mas_centerYWithinMargins {
    return [[MASViewAttribute alloc] initWithView:self layoutAttribute:NSLayoutAttributeCenterYWithinMargins];
}

#endif

#if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 110000) || (__TV_OS_VERSION_MAX_ALLOWED >= 110000)

- (MASViewAttribute *)mas_safeAreaLayoutGuide {
    return [[MASViewAttribute alloc] initWithView:self item:self.safeAreaLayoutGuide layoutAttribute:NSLayoutAttributeBottom];
}
- (MASViewAttribute *)mas_safeAreaLayoutGuideTop {
    return [[MASViewAttribute alloc] initWithView:self item:self.safeAreaLayoutGuide layoutAttribute:NSLayoutAttributeTop];
}
- (MASViewAttribute *)mas_safeAreaLayoutGuideBottom {
    return [[MASViewAttribute alloc] initWithView:self item:self.safeAreaLayoutGuide layoutAttribute:NSLayoutAttributeBottom];
}
- (MASViewAttribute *)mas_safeAreaLayoutGuideLeft {
    return [[MASViewAttribute alloc] initWithView:self item:self.safeAreaLayoutGuide layoutAttribute:NSLayoutAttributeLeft];
}
- (MASViewAttribute *)mas_safeAreaLayoutGuideRight {
    return [[MASViewAttribute alloc] initWithView:self item:self.safeAreaLayoutGuide layoutAttribute:NSLayoutAttributeRight];
}

#endif

#pragma mark - associated properties

- (id)mas_key {
    return objc_getAssociatedObject(self, @selector(mas_key));
}

- (void)setMas_key:(id)key {
    objc_setAssociatedObject(self, @selector(mas_key), key, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

#pragma mark - heirachy

- (instancetype)mas_closestCommonSuperview:(MAS_VIEW *)view {
    MAS_VIEW *closestCommonSuperview = nil;

    MAS_VIEW *secondViewSuperview = view;
    while (!closestCommonSuperview && secondViewSuperview) {
        MAS_VIEW *firstViewSuperview = self;
        while (!closestCommonSuperview && firstViewSuperview) {
            if (secondViewSuperview == firstViewSuperview) {
                closestCommonSuperview = secondViewSuperview;
            }
            firstViewSuperview = firstViewSuperview.superview;
        }
        secondViewSuperview = secondViewSuperview.superview;
    }
    return closestCommonSuperview;
}

@end


================================================
FILE: KJBannerViewDemo/Masonry/View+MASShorthandAdditions.h
================================================
//
//  UIView+MASShorthandAdditions.h
//  Masonry
//
//  Created by Jonas Budelmann on 22/07/13.
//  Copyright (c) 2013 Jonas Budelmann. All rights reserved.
//

#import "View+MASAdditions.h"

#ifdef MAS_SHORTHAND

/**
 *	Shorthand view additions without the 'mas_' prefixes,
 *  only enabled if MAS_SHORTHAND is defined
 */
@interface MAS_VIEW (MASShorthandAdditions)

@property (nonatomic, strong, readonly) MASViewAttribute *left;
@property (nonatomic, strong, readonly) MASViewAttribute *top;
@property (nonatomic, strong, readonly) MASViewAttribute *right;
@property (nonatomic, strong, readonly) MASViewAttribute *bottom;
@property (nonatomic, strong, readonly) MASViewAttribute *leading;
@property (nonatomic, strong, readonly) MASViewAttribute *trailing;
@property (nonatomic, strong, readonly) MASViewAttribute *width;
@property (nonatomic, strong, readonly) MASViewAttribute *height;
@property (nonatomic, strong, readonly) MASViewAttribute *centerX;
@property (nonatomic, strong, readonly) MASViewAttribute *centerY;
@property (nonatomic, strong, readonly) MASViewAttribute *baseline;
@property (nonatomic, strong, readonly) MASViewAttribute *(^attribute)(NSLayoutAttribute attr);

#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100)

@property (nonatomic, strong, readonly) MASViewAttribute *firstBaseline;
@property (nonatomic, strong, readonly) MASViewAttribute *lastBaseline;

#endif

#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000)

@property (nonatomic, strong, readonly) MASViewAttribute *leftMargin;
@property (nonatomic, strong, readonly) MASViewAttribute *rightMargin;
@property (nonatomic, strong, readonly) MASViewAttribute *topMargin;
@property (nonatomic, strong, readonly) MASViewAttribute *bottomMargin;
@property (nonatomic, strong, readonly) MASViewAttribute *leadingMargin;
@property (nonatomic, strong, readonly) MASViewAttribute *trailingMargin;
@property (nonatomic, strong, readonly) MASViewAttribute *centerXWithinMargins;
@property (nonatomic, strong, readonly) MASViewAttribute *centerYWithinMargins;

#endif

#if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 110000) || (__TV_OS_VERSION_MAX_ALLOWED >= 110000)

@property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideTop API_AVAILABLE(ios(11.0),tvos(11.0));
@property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideBottom API_AVAILABLE(ios(11.0),tvos(11.0));
@property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideLeft API_AVAILABLE(ios(11.0),tvos(11.0));
@property (nonatomic, strong, readonly) MASViewAttribute *safeAreaLayoutGuideRight API_AVAILABLE(ios(11.0),tvos(11.0));

#endif

- (NSArray *)makeConstraints:(void(^)(MASConstraintMaker *make))block;
- (NSArray *)updateConstraints:(void(^)(MASConstraintMaker *make))block;
- (NSArray *)remakeConstraints:(void(^)(MASConstraintMaker *make))block;

@end

#define MAS_ATTR_FORWARD(attr)  \
- (MASViewAttribute *)attr {    \
    return [self mas_##attr];   \
}

@implementation MAS_VIEW (MASShorthandAdditions)

MAS_ATTR_FORWARD(top);
MAS_ATTR_FORWARD(left);
MAS_ATTR_FORWARD(bottom);
MAS_ATTR_FORWARD(right);
MAS_ATTR_FORWARD(leading);
MAS_ATTR_FORWARD(trailing);
MAS_ATTR_FORWARD(width);
MAS_ATTR_FORWARD(height);
MAS_ATTR_FORWARD(centerX);
MAS_ATTR_FORWARD(centerY);
MAS_ATTR_FORWARD(baseline);

#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000) || (__MAC_OS_X_VERSION_MIN_REQUIRED >= 101100)

MAS_ATTR_FORWARD(firstBaseline);
MAS_ATTR_FORWARD(lastBaseline);

#endif

#if (__IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (__TV_OS_VERSION_MIN_REQUIRED >= 9000)

MAS_ATTR_FORWARD(leftMargin);
MAS_ATTR_FORWARD(rightMargin);
MAS_ATTR_FORWARD(topMargin);
MAS_ATTR_FORWARD(bottomMargin);
MAS_ATTR_FORWARD(leadingMargin);
MAS_ATTR_FORWARD(trailingMargin);
MAS_ATTR_FORWARD(centerXWithinMargins);
MAS_ATTR_FORWARD(centerYWithinMargins);

#endif

#if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 110000) || (__TV_OS_VERSION_MAX_ALLOWED >= 110000)

MAS_ATTR_FORWARD(safeAreaLayoutGuideTop);
MAS_ATTR_FORWARD(safeAreaLayoutGuideBottom);
MAS_ATTR_FORWARD(safeAreaLayoutGuideLeft);
MAS_ATTR_FORWARD(safeAreaLayoutGuideRight);

#endif

- (MASViewAttribute *(^)(NSLayoutAttribute))attribute {
    return [self mas_attribute];
}

- (NSArray *)makeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *))block {
    return [self mas_makeConstraints:block];
}

- (NSArray *)updateConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *))block {
    return [self mas_updateConstraints:block];
}

- (NSArray *)remakeConstraints:(void(NS_NOESCAPE ^)(MASConstraintMaker *))block {
    return [self mas_remakeConstraints:block];
}

@end

#endif


================================================
FILE: KJBannerViewDemo/Masonry/ViewController+MASAdditions.h
================================================
//
//  UIViewController+MASAdditions.h
//  Masonry
//
//  Created by Craig Siemens on 2015-06-23.
//
//

#import "MASUtilities.h"
#import "MASConstraintMaker.h"
#import "MASViewAttribute.h"

#ifdef MAS_VIEW_CONTROLLER

@interface MAS_VIEW_CONTROLLER (MASAdditions)

/**
 *	following properties return a new MASViewAttribute with appropriate UILayoutGuide and NSLayoutAttribute
 */
@property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuide;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuide;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuideTop;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_topLayoutGuideBottom;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuideTop;
@property (nonatomic, strong, readonly) MASViewAttribute *mas_bottomLayoutGuideBottom;


@end

#endif


================================================
FILE: KJBannerViewDemo/Masonry/ViewController+MASAdditions.m
================================================
//
//  UIViewController+MASAdditions.m
//  Masonry
//
//  Created by Craig Siemens on 2015-06-23.
//
//

#import "ViewController+MASAdditions.h"

#ifdef MAS_VIEW_CONTROLLER

@implementation MAS_VIEW_CONTROLLER (MASAdditions)

- (MASViewAttribute *)mas_topLayoutGuide {
    return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeBottom];
}
- (MASViewAttribute *)mas_topLayoutGuideTop {
    return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeTop];
}
- (MASViewAttribute *)mas_topLayoutGuideBottom {
    return [[MASViewAttribute alloc] initWithView:self.view item:self.topLayoutGuide layoutAttribute:NSLayoutAttributeBottom];
}

- (MASViewAttribute *)mas_bottomLayoutGuide {
    return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeTop];
}
- (MASViewAttribute *)mas_bottomLayoutGuideTop {
    return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeTop];
}
- (MASViewAttribute *)mas_bottomLayoutGuideBottom {
    return [[MASViewAttribute alloc] initWithView:self.view item:self.bottomLayoutGuide layoutAttribute:NSLayoutAttributeBottom];
}



@end

#endif


================================================
FILE: KJBannerViewDemo/Modules/Controller/DownloadViewController.h
================================================
//
//  DownloadViewController.h
//  KJBannerViewDemo
//
//  Created by 杨科军 on 2020/1/15.
//  Copyright © 2020 杨科军. All rights reserved.
//  https://github.com/yangKJ/KJBannerViewDemo

#import <UIKit/UIKit.h>

NS_ASSUME_NONNULL_BEGIN

@interface DownloadViewController : UIViewController

@end

NS_ASSUME_NONNULL_END


================================================
FILE: KJBannerViewDemo/Modules/Controller/DownloadViewController.m
================================================
//
//  DownloadViewController.m
//  KJBannerViewDemo
//
//  Created by 杨科军 on 2020/1/15.
//  Copyright © 2020 杨科军. All rights reserved.
//  https://github.com/yangKJ/KJBannerViewDemo

#import "DownloadViewController.h"
#import "KJWebImageDownloader.h"
#import "KJBannerHeader.h"
#import "Masonry.h"

@interface DownloadViewController ()
@property (nonatomic,strong) UILabel *downloadLabel;
@property (nonatomic,strong) UILabel *totalLabel;
@property (nonatomic,strong) UILabel *speedLabel;
@property (nonatomic,strong) UILabel *progressLabel;
@property (nonatomic,strong) UIButton *againButton;
@property (nonatomic,strong) UIButton *webButton;

@end

@implementation DownloadViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
    
    [self setupUI];
    [self buttonAction];
}

- (void)setupUI{
    self.view.backgroundColor = UIColor.whiteColor;
    [self.view addSubview:self.downloadLabel];
    [self.view addSubview:self.totalLabel];
    [self.view addSubview:self.speedLabel];
    [self.view addSubview:self.progressLabel];
    [self.view addSubview:self.againButton];
    [self.view addSubview:self.webButton];
    [self.downloadLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.view.mas_safeAreaLayoutGuideTop).offset(60);
        make.left.equalTo(self.view).offset(20);
    }];
    [self.totalLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.downloadLabel.mas_bottom).offset(20);
        make.left.equalTo(self.view).offset(20);
    }];
    [self.speedLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.totalLabel.mas_bottom).offset(20);
        make.left.equalTo(self.view).offset(20);
    }];
    [self.progressLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.equalTo(self.speedLabel.mas_bottom).offset(20);
        make.left.equalTo(self.view).offset(20);
    }];
    [self.againButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.width.equalTo(@150);
        make.height.equalTo(@40);
        make.center.equalTo(self.view);
    }];
    [self.webButton mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.equalTo(self.view).inset(20);
        make.bottom.equalTo(self.view.mas_safeAreaLayoutGuideBottom).inset(40);
        make.height.equalTo(@180);
    }];
}

#pragma mark - action

- (void)buttonAction{
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{
        __weak __typeof(self) weakself = self;
        NSString * url = @"https://mp4.vjshi.com/2018-03-30/1f36dd9819eeef0bc508414494d34ad9.mp4";
        [KJWebImageDownloader kj_downloadDataWithURL:url progress:^(KJBannerDownloadProgress * pro) {
            [weakself displayProgress:pro];
        }];
    });
}

- (void)displayProgress:(KJBannerDownloadProgress *)pro{
    dispatch_async(dispatch_get_main_queue(), ^{
        self.downloadLabel.text = [NSString stringWithFormat:@"已下载:%.2fkb",pro.downloadBytes/1024.];
        self.totalLabel.text = [NSString stringWithFormat:@"总大小:%.2fkb",pro.totalBytes/1024.];
        self.speedLabel.text = [NSString stringWithFormat:@"下载速度:%.2fkb/s",pro.speed];
        self.progressLabel.text = [NSString stringWithFormat:@"下载进度:%.5f",pro.progress];
    });
}

#pragma mark - lazy

- (UILabel *)downloadLabel{
    if (!_downloadLabel) {
        _downloadLabel = [[UILabel alloc] init];
        _downloadLabel.textColor = UIColor.blueColor;
        _downloadLabel.font = [UIFont systemFontOfSize:14];
    }
    return _downloadLabel;
}
- (UILabel *)totalLabel{
    if (!_totalLabel) {
        _totalLabel = [[UILabel alloc] init];
        _totalLabel.textColor = UIColor.blueColor;
        _totalLabel.font = [UIFont systemFontOfSize:14];
    }
    return _totalLabel;
}
- (UILabel *)speedLabel{
    if (!_speedLabel) {
        _speedLabel = [[UILabel alloc] init];
        _speedLabel.textColor = UIColor.blueColor;
        _speedLabel.font = [UIFont systemFontOfSize:14];
    }
    return _speedLabel;
}
- (UILabel *)progressLabel{
    if (!_progressLabel) {
        _progressLabel = [[UILabel alloc] init];
        _progressLabel.textColor = UIColor.blueColor;
        _progressLabel.font = [UIFont systemFontOfSize:14];
    }
    return _progressLabel;
}
- (UIButton *)againButton{
    if (!_againButton) {
        _againButton = [UIButton buttonWithType:(UIButtonTypeCustom)];
        _againButton.backgroundColor = UIColor.yellowColor;
        [_againButton setTitle:@"重新获取" forState:(UIControlStateNormal)];
        [_againButton setTitleColor:UIColor.blueColor forState:(UIControlStateNormal)];
        [_againButton addTarget:self action:@selector(buttonAction)
               forControlEvents:(UIControlEventTouchUpInside)];
    }
    return _againButton;
}
- (UIButton *)webButton{
    if (!_webButton) {
        _webButton = [UIButton buttonWithType:(UIButtonTypeCustom)];
        _webButton.backgroundColor = [UIColor.greenColor colorWithAlphaComponent:0.3];
        NSURL * URL = [NSURL URLWithString:@"http://photos.tuchong.com/285606/f/4374153.jpg"];
        [_webButton kj_setImageWithURL:URL provider:nil];
    }
    return _webButton;
}

@end


================================================
FILE: KJBannerViewDemo/Modules/Controller/ViewController.h
================================================
//
//  ViewController.h
//  KJBannerViewDemo
//
//  Created by 杨科军 on 2018/12/22.
//  Copyright © 2018 杨科军. All rights reserved.
//  https://github.com/yangKJ/KJBannerViewDemo

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController


@end



================================================
FILE: KJBannerViewDemo/Modules/Controller/ViewController.m
================================================
//
//  ViewController.m
//  KJBannerViewDemo
//
//  Created by 杨科军 on 2018/12/22.
//  Copyright © 2018 杨科军. All rights reserved.
//  https://github.com/yangKJ/KJBannerViewDemo

#import "ViewController.h"
#import "KJBannerHeader.h"
#import "KJCollectionViewCell.h"
#import "DownloadViewController.h"
#import "KJViewModel.h"
#import "Masonry.h"

@interface ViewController ()<KJBannerViewDelegate,KJBannerViewDataSource>
@property (weak, nonatomic) IBOutlet KJBannerView *banner;
@property (weak, nonatomic) IBOutlet KJBannerView *banner3;
@property (weak, nonatomic) IBOutlet UIView *backView;
@property (weak, nonatomic) IBOutlet UIButton *button;
@property (weak, nonatomic) IBOutlet UISwitch *Switch;
@property (weak, nonatomic) IBOutlet UILabel *label;
@property (nonatomic,strong) KJBannerView *banner2;
@property (nonatomic,strong) NSArray *datas;
@property (nonatomic,strong) NSArray *banner3Datas;
@property (nonatomic,strong) KJViewModel *viewModel;

@end

@implementation ViewController

- (void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    [self.banner kj_repauseTimer];
    [self.banner2 kj_repauseTimer];
}
- (void)viewDidDisappear:(BOOL)animated{
    [super viewDidDisappear:animated];
    [self.banner kj_pauseTimer];
    [self.banner2 kj_pauseTimer];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    [self setupUI];
    [self setText];
    [self setXib];
    [self setMasonry];
    
    [self _bingViewModel];
}

- (void)setupUI{
    BOOL isPhoneX = ({
        BOOL isPhoneX = NO;
        if (@available(iOS 13.0, *)) {
            isPhoneX = [UIApplication sharedApplication].windows.firstObject.safeAreaInsets.bottom > 0.0;
        } else if (@available(iOS 11.0, *)) {
            isPhoneX = [[UIApplication sharedApplication] delegate].window.safeAreaInsets.bottom > 0.0;
        }
        (isPhoneX);
    });
    [self.button addTarget:self action:@selector(clearAction) forControlEvents:(UIControlEventTouchUpInside)];
    [self.Switch addTarget:self action:@selector(qiehuanAction:) forControlEvents:(UIControlEventValueChanged)];
    UIButton *button = [UIButton buttonWithType:(UIButtonTypeCustom)];
    button.frame = CGRectMake(10, self.view.frame.size.height-100-(isPhoneX ? 34.0f : 0.0f), self.view.frame.size.width-20, 100);
    NSDictionary *attributes = @{
        NSUnderlineStyleAttributeName:@(NSUnderlineStyleSingle),
        NSForegroundColorAttributeName:UIColor.redColor
    };
    NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc]
                                          initWithString:@"大家觉得好用还请点个星,遇见什么问题也可issues,持续更新ing.."
                                          attributes:attributes];
    [button setAttributedTitle:attrStr forState:(UIControlStateNormal)];
    button.titleLabel.numberOfLines = 0;
    button.titleLabel.textAlignment = 1;
    [button addTarget:self action:@selector(kj_button) forControlEvents:(UIControlEventTouchUpInside)];
    [self.view addSubview:button];
    self.Switch.on = NO;
}

- (void)setText{
    self.banner3.dataSource = self;
    self.banner3.showPageControl = NO;
    self.banner3.rollType = KJBannerViewRollDirectionTypeBottomToTop;
    [self.banner3 registerClass:[KJCollectionViewCell class] forCellWithReuseIdentifier:@"banner3"];
    self.banner3Datas = @[
        @"测试文本滚动",
        @"觉得好用请给我点个星",
        @"有什么问题也可以联系我",
        @"邮箱: ykj310@126.com"
    ];
    [self.banner3 reloadData];
}
- (void)setXib{
    self.banner.delegate = self;
    self.banner.dataSource = self;
    self.banner.pageControl.pageType = PageControlStyleRectangle;
    self.banner.pageControl.selectColor = UIColor.greenColor;
    self.banner.pageControl.dotwidth = 20;
    self.banner.pageControl.dotheight = 2;
    self.banner.pageControl.displayType = KJPageControlDisplayTypeLeft;
    self.banner.pageControl.backgroundColor = [UIColor.blackColor colorWithAlphaComponent:0.5];
    self.banner.rollType = KJBannerViewRollDirectionTypeBottomToTop;
    [self.banner registerClass:[KJBannerViewCell class] forCellWithReuseIdentifier:@"KJBannerViewCell"];
    
    self.datas = @[
        @"IMG_Guitar_52",
        @"IMG_0139",
        @"http://photos.tuchong.com/285606/f/4374153.jpg",
        @"https://up.54fcnr.com/pic_source/f7/1f/5d/f71f5d3cbf13f1f0f7da798aa8ddb4f9.gif",
    ];
    [self.banner reloadData];
}
- (void)setMasonry{
    [self.backView addSubview:self.banner2];
    [self.banner2 mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.left.right.bottom.equalTo(self.backView);
    }];
    [self.banner2 kj_useMasonry];
}

#pragma mark - setDatas

- (void)_bingViewModel{
    self.viewModel = [[KJViewModel alloc] init];
    [self.viewModel refresh:^(NSArray * _Nonnull datas) {
        [self.banner2 reloadData];
    } haveDatas:NO];
    self.label.text = [NSString stringWithFormat:@"缓存大小:%.02f MB", [KJViewModel cacheSize]];
}

#pragma mark - action

- (void)kj_button{
    NSURL * url = [NSURL URLWithString:@"https://github.com/yangKJ/KJBannerViewDemo"];
    [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
}

- (void)qiehuanAction:(UISwitch *)sender{
    [self.viewModel refresh:^(NSArray * _Nonnull datas) {
        [self.banner2 reloadData];
    } haveDatas:sender.on];
}
- (void)clearAction{
    [KJViewModel clearCache];
    self.label.text = [NSString stringWithFormat:@"缓存大小:%.02f MB", [KJViewModel cacheSize]];
}
- (IBAction)pauseRoll:(UIButton *)sender {
    [self.banner kj_pauseTimer];
    [self.banner2 kj_pauseTimer];
    [self.banner3 kj_pauseTimer];
}
- (IBAction)repauseRoll:(UIButton *)sender {
    [self.banner kj_repauseTimer];
    [self.banner2 kj_repauseTimer];
    [self.banner3 kj_repauseTimer];
}

#pragma mark - KJBannerViewDelegate

- (void)kj_bannerView:(KJBannerView *)banner didSelectItemAtIndex:(NSInteger)index{
    DownloadViewController *vc = [DownloadViewController new];
    [self.navigationController pushViewController:vc animated:YES];
}

- (void)kj_bannerView:(KJBannerView *)banner loopScrolledItemAtIndex:(NSInteger)index{

}

#pragma mark - KJBannerViewDataSource

- (NSInteger)kj_numberOfItemsInBannerView:(KJBannerView *)banner {
    if (banner == self.banner) {
        return self.datas.count;
    } else if (banner == self.banner2) {
        return self.viewModel.datas.count;
    }
    return self.banner3Datas.count;
}

- (__kindof KJBannerViewCell *)kj_bannerView:(KJBannerView *)banner cellForItemAtIndex:(NSInteger)index {
    if (banner == self.banner) {
        KJBannerViewCell *cell = [banner dequeueReusableCellWithReuseIdentifier:@"KJBannerViewCell" forIndex:index];
        cell.bannerContentMode = UIViewContentModeScaleAspectFill;
        cell.bannerCornerRadius = UIRectCornerTopRight | UIRectCornerBottomLeft | UIRectCornerBottomRight;
        cell.bannerNoPureBack = YES;
        cell.bannerRadius = 50;
        [cell setupImageURLString:self.datas[index] mineLoadImage:YES];
        return cell;
    } else if (banner == self.banner2) {
        KJBannerViewCell *cell = [banner dequeueReusableCellWithReuseIdentifier:@"banner2" forIndex:index];
        cell.bannerRadius = 20;
        cell.bannerNoPureBack = YES;
        cell.bannerRadiusColor = self.backView.backgroundColor;
        KJBannerModel *model = self.viewModel.datas[index];
        [cell setupImageURLString:model.customImageUrl mineLoadImage:YES];
        return cell;
    }
    KJCollectionViewCell *cell = [banner dequeueReusableCellWithReuseIdentifier:@"banner3" forIndex:index];
    cell.title = self.banner3Datas[index];
    return cell;
}

#pragma mark - lazy

- (KJBannerView *)banner2{
    if (!_banner2) {
        _banner2 = [[KJBannerView alloc] init];
        _banner2.delegate = self;
        _banner2.dataSource = self;
        _banner2.autoTime = 3;
        _banner2.isZoom = YES;
        _banner2.itemSpace = -10;
        CGSize size = CGSizeApplyAffineTransform(self.backView.frame.size, CGAffineTransformMakeScale(.7, .7));
        _banner2.itemWidth = size.width;
        _banner2.pageControl.pageType = PageControlStyleSizeDot;
        _banner2.pageControl.displayType = KJPageControlDisplayTypeRight;
        _banner2.pageControl.backgroundColor = [UIColor.blackColor colorWithAlphaComponent:0.5];
        [_banner2 registerClass:[KJBannerViewCell class] forCellWithReuseIdentifier:@"banner2"];
    }
    return _banner2;
}

@end


================================================
FILE: KJBannerViewDemo/Modules/Model/KJBannerModel.h
================================================
//
//  KJBannerModel.h
//  KJBannerViewDemo
//
//  Created by 杨科军 on 2019/1/12.
//  Copyright © 2019 杨科军. All rights reserved.
//  https://github.com/yangKJ/KJBannerViewDemo

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

NS_ASSUME_NONNULL_BEGIN

@interface KJBannerModel : NSObject

@property (nonatomic,strong) NSString *customImageUrl;
@property (nonatomic,strong) NSString *customTitle;
@property (nonatomic,strong) UIImage *customImage;

//获取当前设备可用内存
+ (double)availableMemory;

//获取当前任务所占用内存
+ (double)usedMemory;

@end

NS_ASSUME_NONNULL_END


================================================
FILE: KJBannerViewDemo/Modules/Model/KJBannerModel.m
================================================
//
//  KJBannerModel.m
//  KJBannerViewDemo
//
//  Created by 杨科军 on 2019/1/12.
//  Copyright © 2019 杨科军. All rights reserved.
//  https://github.com/yangKJ/KJBannerViewDemo

#import "KJBannerModel.h"
#import <sys/sysctl.h>
#import <mach/mach.h>

@implementation KJBannerModel

//获取当前设备可用内存
+ (double)availableMemory{
    vm_statistics_data_t vmStats;
    mach_msg_type_number_t infoCount = HOST_VM_INFO_COUNT;
    kern_return_t kernReturn = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&vmStats, &infoCount);
    if (kernReturn != KERN_SUCCESS) {
        return NSNotFound;
    }
    return ((vm_page_size * vmStats.free_count)/1024.0)/1024.0;
}

//获取当前任务所占用内存
+ (double)usedMemory{
    task_basic_info_data_t taskInfo;
    mach_msg_type_number_t infoCount = TASK_BASIC_INFO_COUNT;
    kern_return_t kernReturn = task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&taskInfo, &infoCount);
    if (kernReturn != KERN_SUCCESS) {
        return NSNotFound;
    }
    return taskInfo.resident_size/1024.0/1024.0;
}

@end


================================================
FILE: KJBannerViewDemo/Modules/View/KJCollectionViewCell.h
================================================
//
//  KJCollectionViewCell.h
//  KJBannerViewDemo
//
//  Created by 杨科军 on 2019/1/13.
//  Copyright © 2019 杨科军. All rights reserved.
//  https://github.com/yangKJ/KJBannerViewDemo

#import "KJBannerViewCell.h"
#import "KJBannerModel.h"

NS_ASSUME_NONNULL_BEGIN

@interface KJCollectionViewCell : KJBannerViewCell

@property (nonatomic, strong) NSString *title;

@end

NS_ASSUME_NONNULL_END


================================================
FILE: KJBannerViewDemo/Modules/View/KJCollectionViewCell.m
================================================
//
//  KJCollectionViewCell.m
//  KJBannerViewDemo
//
//  Created by 杨科军 on 2019/1/13.
//  Copyright © 2019 杨科军. All rights reserved.
//  https://github.com/yangKJ/KJBannerViewDemo

#import "KJCollectionViewCell.h"

@interface KJCollectionViewCell ()

@property (strong, nonatomic) UILabel *label;

@end

@implementation KJCollectionViewCell

- (instancetype)initWithFrame:(CGRect)frame{
    if (self = [super initWithFrame:frame]) {
        [self.contentView addSubview:self.label];
    }
    return self;
}

- (void)setTitle:(NSString *)title{
    self.label.text = title;
}

- (UILabel *)label{
    if (!_label) {
        _label = [[UILabel alloc]initWithFrame:self.bounds];
        _label.textColor = UIColor.blackColor;
        _label.font = [UIFont boldSystemFontOfSize:16];
    }
    return _label;
}

@end


================================================
FILE: KJBannerViewDemo/Modules/ViewModel/KJViewModel.h
================================================
//
//  KJViewModel.h
//  KJBannerViewDemo
//
//  Created by 77。 on 2020/9/18.
//  Copyright © 2020 杨科军. All rights reserved.
//  https://github.com/yangKJ/KJBannerViewDemo

#import <Foundation/Foundation.h>
#import "KJBannerModel.h"

NS_ASSUME_NONNULL_BEGIN

@interface KJViewModel : NSObject

@property (nonatomic, strong) NSArray<KJBannerModel *> *datas;

/// 模拟网络请求
/// @param refresh 请求回调
/// @param have 是否有数据
- (void)refresh:(void(^)(NSArray<KJBannerModel *>* datas))refresh haveDatas:(BOOL)have;

/// 缓存大小
+ (CGFloat)cacheSize;

/// 清除缓存
+ (void)clearCache;

@end

NS_ASSUME_NONNULL_END


================================================
FILE: KJBannerViewDemo/Modules/ViewModel/KJViewModel.m
================================================
//
//  KJViewModel.m
//  KJBannerViewDemo
//
//  Created by 77。 on 2020/9/18.
//  Copyright © 2020 杨科军. All rights reserved.
//  https://github.com/yangKJ/KJBannerViewDemo

#import "KJViewModel.h"
#import "KJImageCache.h"
#import "KJBannerViewTimer.h"

#define gif @"https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/"\
"7a00f7f6c0c744a893f304a7d3b629b5~tplv-k3u1fbpfcp-watermark.image?"

#define tu1 @"https://img.jwfzl.com.cn/storage/20210422/60810d41b6303.jpeg"
#define tu2 @"http://photos.tuchong.com/285606/f/4374153.jpg"
#define tu3 @"https://tfile.melinked.com/2021/01/5c071de1-b7e9-4bf4-a1f7-a2f35eff9ed6.jpg"

@implementation KJViewModel

/// 模拟网络请求
/// @param refresh 请求回调
/// @param have 是否有数据
- (void)refresh:(void(^)(NSArray<KJBannerModel *>* datas))refresh haveDatas:(BOOL)have{
    if (have == NO) {
//        KJBannerModel *model = [[KJBannerModel alloc]init];
//        model.customImageUrl = gif;
//        model.customTitle = @"单图";
//        self.datas = @[model];
        self.datas = @[];
        refresh ? refresh(self.datas) : nil;
        return;
    }
    NSMutableArray *array = [NSMutableArray array];
    dispatch_group_t dispatchGroup = dispatch_group_create();
    dispatch_group_enter(dispatchGroup);
    dispatch_group_async(dispatchGroup, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)),
                       dispatch_get_global_queue(0, 0), ^{
            NSArray *images = @[tu3,tu2,tu1];
            for (int i = 0; i < images.count; i++) {
                KJBannerModel *model = [[KJBannerModel alloc]init];
                model.customImageUrl = images[i];
                model.customTitle = [NSString stringWithFormat:@"A线程图片名称:%d",i];
                [array addObject:model];
            }
            dispatch_group_leave(dispatchGroup);
        });
    });
    dispatch_group_enter(dispatchGroup);
    dispatch_group_async(dispatchGroup, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)),
                       dispatch_get_global_queue(0, 0), ^{
            NSArray *images = @[@"",@"xsi"];
            for (int i = 0; i < images.count; i++) {
                KJBannerModel *model = [[KJBannerModel alloc]init];
                model.customImageUrl = images[i];
                model.customTitle = @"B线程图片地址";
                [array addObject:model];
            }
            dispatch_group_leave(dispatchGroup);
        });
    });
    dispatch_group_notify(dispatchGroup, dispatch_get_main_queue(), ^(){
        self.datas = array.mutableCopy;
        refresh ? refresh(array) : nil;
    });
}

/// 缓存大小
+ (CGFloat)cacheSize{
    return [KJImageCache kj_getLocalityImageCacheSize] / 1024 / 1024.0;
}

/// 清除缓存
+ (void)clearCache{
    [KJImageCache kj_clearLocalityImageAndCache];
}

@end


================================================
FILE: KJBannerViewDemo/Supporting Files/Assets.xcassets/AppIcon.appiconset/Contents.json
================================================
{
  "images" : [
    {
      "size" : "20x20",
      "idiom" : "iphone",
      "filename" : "WechatIMG44iPhoneNotification_20pt@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "20x20",
      "idiom" : "iphone",
      "filename" : "WechatIMG44iPhoneNotification_20pt@3x.png",
      "scale" : "3x"
    },
    {
      "size" : "29x29",
      "idiom" : "iphone",
      "filename" : "WechatIMG44iPhoneSpootlight5_29pt@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "29x29",
      "idiom" : "iphone",
      "filename" : "WechatIMG44iPhoneSpootlight5_29pt@3x.png",
      "scale" : "3x"
    },
    {
      "size" : "40x40",
      "idiom" : "iphone",
      "filename" : "WechatIMG44iPhoneSpootlight7_40pt@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "40x40",
      "idiom" : "iphone",
      "filename" : "WechatIMG44iPhoneSpootlight7_40pt@3x.png",
      "scale" : "3x"
    },
    {
      "size" : "60x60",
      "idiom" : "iphone",
      "filename" : "WechatIMG44iPhoneApp_60pt@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "60x60",
      "idiom" : "iphone",
      "filename" : "WechatIMG44iPhoneApp_60pt@3x.png",
      "scale" : "3x"
    },
    {
      "size" : "20x20",
      "idiom" : "ipad",
      "filename" : "WechatIMG44iPadNotifications_20pt.png",
      "scale" : "1x"
    },
    {
      "size" : "20x20",
      "idiom" : "ipad",
      "filename" : "WechatIMG44iPadNotifications_20pt@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "29x29",
      "idiom" : "ipad",
      "filename" : "WechatIMG44iPadSpootlight5_29pt.png",
      "scale" : "1x"
    },
    {
      "size" : "29x29",
      "idiom" : "ipad",
      "filename" : "WechatIMG44iPadSpootlight5_29pt@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "40x40",
      "idiom" : "ipad",
      "filename" : "WechatIMG44iPadSpootlight7_40pt.png",
      "scale" : "1x"
    },
    {
      "size" : "40x40",
      "idiom" : "ipad",
      "filename" : "WechatIMG44iPadSpootlight7_40pt@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "76x76",
      "idiom" : "ipad",
      "filename" : "WechatIMG44iPadApp_76pt.png",
      "scale" : "1x"
    },
    {
      "size" : "76x76",
      "idiom" : "ipad",
      "filename" : "WechatIMG44iPadApp_76pt@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "83.5x83.5",
      "idiom" : "ipad",
      "filename" : "WechatIMG44iPadProApp_83.5pt@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "1024x1024",
      "idiom" : "ios-marketing",
      "filename" : "WechatIMG44store_1024pt.png",
      "scale" : "1x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}

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


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

================================================
FILE: KJBannerViewDemo/Supporting Files/Assets.xcassets/IMG_4931.imageset/Contents.json~Add 2.0.3
================================================
{
  "images" : [
    {
      "idiom" : "universal",
      "filename" : "IMG_4931.jpg",
      "scale" : "1x"
    },
    {
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}

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

================================================
FILE: KJBannerViewDemo/Supporting Files/Assets.xcassets/IMG_Guitar_52.imageset/Contents.json
================================================
{
  "images" : [
    {
      "idiom" : "universal",
      "filename" : "jita.png",
      "scale" : "1x"
    },
    {
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}

================================================
FILE: KJBannerViewDemo/Supporting Files/Assets.xcassets/ax.imageset/Contents.json
================================================
{
  "images" : [
    {
      "filename" : "0161da5541af81000001a64bc753a4.jpg@1280w_1l_2o_100sh.jpg",
      "idiom" : "universal",
      "scale" : "1x"
    },
    {
      "idiom" : "universal",
      "scale" : "2x"
    },
    {
      "idiom" : "universal",
      "scale" : "3x"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  }
}


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


================================================
FILE: KJBannerViewDemo/Supporting Files/Base.lproj/LaunchScreen.storyboard
================================================
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="15705" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
    <device id="retina4_7" orientation="portrait" appearance="light"/>
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="15706"/>
        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
        <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">
                    <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"/>
                        <subviews>
                            <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="KJBannerViewDemo" textAlignment="center" lineBreakMode="middleTruncation" baselineAdjustment="alignBaselines" minimumFontSize="18" translatesAutoresizingMaskIntoConstraints="NO" id="xRb-a6-OYG">
                                <rect key="frame" x="24.5" y="249" width="326.5" height="41"/>
                                <fontDescription key="fontDescription" type="boldSystem" pointSize="34"/>
                                <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
                                <nil key="highlightedColor"/>
                            </label>
                            <label opaque="NO" clipsSubviews="YES" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="  Copyright (c) 2018年 杨科军. All rights reserved." textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="9" translatesAutoresizingMaskIntoConstraints="NO" id="fir-tf-Ftv">
                                <rect key="frame" x="18.5" y="629" width="338.5" height="18"/>
                                <fontDescription key="fontDescription" type="system" pointSize="15"/>
                                <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
                                <nil key="highlightedColor"/>
                            </label>
                        </subviews>
                        <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <constraints>
                            <constraint firstItem="xRb-a6-OYG" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="5zu-qr-fbb"/>
                            <constraint firstItem="fir-tf-Ftv" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="mSq-hl-qiL"/>
                            <constraint firstItem="xRb-a6-OYG" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" constant="-64" id="oDP-RL-gUP"/>
                            <constraint firstItem="6Tk-OE-BBY" firstAttribute="bottom" secondItem="fir-tf-Ftv" secondAttribute="bottom" constant="20" id="tjw-FC-MVF"/>
                        </constraints>
                        <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
                    </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: KJBannerViewDemo/Supporting Files/Base.lproj/Main.storyboard
================================================
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19162" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="uBS-w7-M4r">
    <device id="retina4_7" orientation="portrait" appearance="light"/>
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19144"/>
        <capability name="Safe area layout guides" minToolsVersion="9.0"/>
        <capability name="System colors in document resources" minToolsVersion="11.0"/>
        <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
    </dependencies>
    <scenes>
        <!--KJBannerViewDemo ⛳️-->
        <scene sceneID="tne-QT-ifu">
            <objects>
                <viewController id="BYZ-38-t0r" customClass="ViewController" sceneMemberID="viewController">
                    <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="6Ix-O9-EeV" customClass="KJBannerView">
                                <rect key="frame" x="12.5" y="64" width="350" height="175"/>
                                <color key="backgroundColor" systemColor="systemIndigoColor"/>
                                <constraints>
                                    <constraint firstAttribute="width" constant="350" id="Ege-D7-jvB"/>
                                    <constraint firstAttribute="width" secondItem="6Ix-O9-EeV" secondAttribute="height" multiplier="2:1" id="nHw-c3-qd7"/>
                                </constraints>
                                <userDefinedRuntimeAttributes>
                                    <userDefinedRuntimeAttribute type="number" keyPath="autoTime">
                                        <real key="value" value="3"/>
                                    </userDefinedRuntimeAttribute>
                                    <userDefinedRuntimeAttribute type="image" keyPath="placeholderImage" value="KJBannerPlaceholderImage.png"/>
                                    <userDefinedRuntimeAttribute type="number" keyPath="rollType">
                                        <integer key="value" value="3"/>
                                    </userDefinedRuntimeAttribute>
                                </userDefinedRuntimeAttributes>
                            </view>
                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="cfo-aw-2br">
                                <rect key="frame" x="12.5" y="259" width="350" height="140"/>
                                <color key="backgroundColor" red="0.30980392159999998" green="0.56078431370000004" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                                <constraints>
                                    <constraint firstAttribute="width" secondItem="cfo-aw-2br" secondAttribute="height" multiplier="5:2" id="HdV-df-WcK"/>
                                </constraints>
                            </view>
                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="缓存数据" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="OsQ-Te-g5f">
                                <rect key="frame" x="12.5" y="419" width="61.5" height="18"/>
                                <fontDescription key="fontDescription" type="system" pointSize="15"/>
                                <nil key="textColor"/>
                                <nil key="highlightedColor"/>
                            </label>
                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="352-Wp-Xyg">
                                <rect key="frame" x="296.5" y="412" width="66" height="32"/>
                                <fontDescription key="fontDescription" type="system" pointSize="16"/>
                                <state key="normal" title="清除缓存"/>
                            </button>
                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="切换数据" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="WrR-yr-iqv">
                                <rect key="frame" x="12.5" y="457" width="61.5" height="18"/>
                                <fontDescription key="fontDescription" type="system" pointSize="15"/>
                                <nil key="textColor"/>
                                <nil key="highlightedColor"/>
                            </label>
                            <switch opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" contentHorizontalAlignment="center" contentVerticalAlignment="center" on="YES" translatesAutoresizingMaskIntoConstraints="NO" id="eT1-C3-BDb">
                                <rect key="frame" x="114" y="450.5" width="51" height="31"/>
                            </switch>
                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="W4X-vq-w6K">
                                <rect key="frame" x="300.5" y="451" width="62" height="30"/>
                                <state key="normal" title="继续滚动"/>
                                <connections>
                                    <action selector="repauseRoll:" destination="BYZ-38-t0r" eventType="touchUpInside" id="xxa-e8-U2s"/>
                                </connections>
                            </button>
                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Me2-Ly-rvC">
                                <rect key="frame" x="203.5" y="451" width="62" height="30"/>
                                <state key="normal" title="暂停滚动"/>
                                <connections>
                                    <action selector="pauseRoll:" destination="BYZ-38-t0r" eventType="touchUpInside" id="jjQ-qm-suG"/>
                                </connections>
                            </button>
                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XHz-S7-bGJ" customClass="KJBannerView">
                                <rect key="frame" x="12.5" y="501.5" width="350" height="30"/>
                                <color key="backgroundColor" red="0.089175753231749214" green="0.46275906735751293" blue="0.15783085618148435" alpha="0.096390845070422532" colorSpace="custom" customColorSpace="displayP3"/>
                                <constraints>
                                    <constraint firstAttribute="height" constant="30" id="NFG-rG-nR6"/>
                                </constraints>
                            </view>
                        </subviews>
                        <viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
                        <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <constraints>
                            <constraint firstItem="W4X-vq-w6K" firstAttribute="centerY" secondItem="Me2-Ly-rvC" secondAttribute="centerY" id="4IK-gE-ndv"/>
                            <constraint firstItem="cfo-aw-2br" firstAttribute="top" secondItem="6Ix-O9-EeV" secondAttribute="bottom" constant="20" id="8ub-Ie-jlb"/>
                            <constraint firstItem="Me2-Ly-rvC" firstAttribute="leading" secondItem="eT1-C3-BDb" secondAttribute="trailing" constant="40.5" id="9HR-ei-dgm"/>
                            <constraint firstItem="6Ix-O9-EeV" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="CMP-jO-eHM"/>
                            <constraint firstItem="XHz-S7-bGJ" firstAttribute="top" secondItem="eT1-C3-BDb" secondAttribute="bottom" constant="20" id="Icv-Lo-D0s"/>
                            <constraint firstItem="352-Wp-Xyg" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="OsQ-Te-g5f" secondAttribute="trailing" constant="8" symbolic="YES" id="KhE-nb-ygb"/>
                            <constraint firstItem="W4X-vq-w6K" firstAttribute="trailing" secondItem="6Ix-O9-EeV" secondAttribute="trailing" id="Ouk-tU-RnL"/>
                            <constraint firstItem="eT1-C3-BDb" firstAttribute="centerY" secondItem="WrR-yr-iqv" secondAttribute="centerY" id="QZA-3H-Cjh"/>
                            <constraint firstItem="cfo-aw-2br" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="SUP-0N-OF6"/>
                            <constraint firstItem="XHz-S7-bGJ" firstAttribute="leading" secondItem="cfo-aw-2br" secondAttribute="leading" id="TTF-T0-8kf"/>
                            <constraint firstItem="OsQ-Te-g5f" firstAttribute="top" secondItem="cfo-aw-2br" secondAttribute="bottom" constant="20" id="VbA-9g-a4Y"/>
                            <constraint firstItem="352-Wp-Xyg" firstAttribute="trailing" secondItem="6Ix-O9-EeV" secondAttribute="trailing" id="XI6-lf-gv7"/>
                            <constraint firstItem="W4X-vq-w6K" firstAttribute="centerY" secondItem="eT1-C3-BDb" secondAttribute="centerY" id="ZeX-K9-VWA"/>
                            <constraint firstItem="WrR-yr-iqv" firstAttribute="top" secondItem="OsQ-Te-g5f" secondAttribute="bottom" constant="20" id="Zub-FJ-eWf"/>
                            <constraint firstItem="OsQ-Te-g5f" firstAttribute="leading" secondItem="6Ix-O9-EeV" secondAttribute="leading" id="byA-wQ-FQZ"/>
                            <constraint firstItem="WrR-yr-iqv" firstAttribute="leading" secondItem="6Ix-O9-EeV" secondAttribute="leading" id="eyw-2f-5Hm"/>
                            <constraint firstItem="eT1-C3-BDb" firstAttribute="leading" secondItem="WrR-yr-iqv" secondAttribute="trailing" constant="40" id="gv9-tz-rFm"/>
                            <constraint firstItem="XHz-S7-bGJ" firstAttribute="trailing" secondItem="cfo-aw-2br" secondAttribute="trailing" id="gvC-k2-2rs"/>
                            <constraint firstItem="W4X-vq-w6K" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="Me2-Ly-rvC" secondAttribute="trailing" constant="8" symbolic="YES" id="ld9-2u-A8e"/>
                            <constraint firstItem="6Ix-O9-EeV" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" constant="20" id="nMX-o2-xx8"/>
                            <constraint firstItem="352-Wp-Xyg" firstAttribute="centerY" secondItem="OsQ-Te-g5f" secondAttribute="centerY" id="nvZ-zw-9hS"/>
                            <constraint firstItem="cfo-aw-2br" firstAttribute="width" secondItem="6Ix-O9-EeV" secondAttribute="width" id="ug4-3Q-PBd"/>
                        </constraints>
                    </view>
                    <navigationItem key="navigationItem" title="KJBannerViewDemo ⛳️" id="sNI-AU-iLq"/>
                    <connections>
                        <outlet property="Switch" destination="eT1-C3-BDb" id="ALY-zN-Za0"/>
                        <outlet property="backView" destination="cfo-aw-2br" id="z29-da-fMS"/>
                        <outlet property="banner" destination="6Ix-O9-EeV" id="ZWR-ft-X3m"/>
                        <outlet property="banner3" destination="XHz-S7-bGJ" id="eWL-zD-3Nc"/>
                        <outlet property="button" destination="352-Wp-Xyg" id="peN-2W-Ks0"/>
                        <outlet property="label" destination="OsQ-Te-g5f" id="Eqv-aK-oSn"/>
                    </connections>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="972" y="81"/>
        </scene>
        <!--Navigation Controller-->
        <scene sceneID="voe-hm-P06">
            <objects>
                <navigationController automaticallyAdjustsScrollViewInsets="NO" id="uBS-w7-M4r" sceneMemberID="viewController">
                    <toolbarItems/>
                    <navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="M6z-bY-EvL">
                        <rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
                        <autoresizingMask key="autoresizingMask"/>
                    </navigationBar>
                    <nil name="viewControllers"/>
                    <connections>
                        <segue destination="BYZ-38-t0r" kind="relationship" relationship="rootViewController" id="UCX-4l-537"/>
                    </connections>
                </navigationController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="Lyb-U6-hdo" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="138.40000000000001" y="81.409295352323838"/>
        </scene>
    </scenes>
    <resources>
        <image name="KJBannerPlaceholderImage.png" width="620" height="349"/>
        <systemColor name="systemIndigoColor">
            <color red="0.34509803921568627" green="0.33725490196078434" blue="0.83921568627450982" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
        </systemColor>
    </resources>
</document>


================================================
FILE: KJBannerViewDemo/Supporting Files/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>$(DEVELOPMENT_LANGUAGE)</string>
	<key>CFBundleDisplayName</key>
	<string>BANNER</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>UIMainStoryboardFile</key>
	<string>Main</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>
	<key>UIUserInterfaceStyle</key>
	<string>Light</string>
</dict>
</plist>


================================================
FILE: KJBannerViewDemo/Supporting Files/main.m
================================================
//
//  main.m
//  KJBannerViewDemo
//
//  Created by 杨科军 on 2018/12/22.
//  Copyright © 2018 杨科军. All rights reserved.
//  https://github.com/yangKJ/KJBannerViewDemo

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

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


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

/* Begin PBXBuildFile section */
		684059DD21EA08D00092F630 /* KJBannerModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 684059DC21EA08D00092F630 /* KJBannerModel.m */; };
		684059E121EB59DA0092F630 /* KJCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 684059DF21EB59DA0092F630 /* KJCollectionViewCell.m */; };
		686568CB26FB5EDC0001C691 /* DownloadViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 686568C726FB5EDC0001C691 /* DownloadViewController.m */; };
		686568CC26FB5EDC0001C691 /* KJViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 686568C926FB5EDC0001C691 /* KJViewModel.m */; };
		6868EC2126FB5D54001F2400 /* NSLayoutConstraint+MASDebugAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 6868EC0926FB5D54001F2400 /* NSLayoutConstraint+MASDebugAdditions.m */; };
		6868EC2226FB5D54001F2400 /* ViewController+MASAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 6868EC1226FB5D54001F2400 /* ViewController+MASAdditions.m */; };
		6868EC2326FB5D54001F2400 /* MASCompositeConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 6868EC1626FB5D54001F2400 /* MASCompositeConstraint.m */; };
		6868EC2426FB5D54001F2400 /* MASConstraintMaker.m in Sources */ = {isa = PBXBuildFile; fileRef = 6868EC1726FB5D54001F2400 /* MASConstraintMaker.m */; };
		6868EC2526FB5D54001F2400 /* MASLayoutConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 6868EC1826FB5D54001F2400 /* MASLayoutConstraint.m */; };
		6868EC2626FB5D54001F2400 /* NSArray+MASAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 6868EC1926FB5D54001F2400 /* NSArray+MASAdditions.m */; };
		6868EC2726FB5D54001F2400 /* View+MASAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 6868EC1A26FB5D54001F2400 /* View+MASAdditions.m */; };
		6868EC2826FB5D54001F2400 /* MASConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 6868EC1D26FB5D54001F2400 /* MASConstraint.m */; };
		6868EC2926FB5D54001F2400 /* MASViewConstraint.m in Sources */ = {isa = PBXBuildFile; fileRef = 6868EC1F26FB5D54001F2400 /* MASViewConstraint.m */; };
		6868EC2A26FB5D54001F2400 /* MASViewAttribute.m in Sources */ = {isa = PBXBuildFile; fileRef = 6868EC2026FB5D54001F2400 /* MASViewAttribute.m */; };
		68BD69F82580712000D4B3AF /* IMG_0139.GIF in Resources */ = {isa = PBXBuildFile; fileRef = 68BD69F72580712000D4B3AF /* IMG_0139.GIF */; };
		68E26B5321CE924700F91182 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 68E26B5221CE924700F91182 /* AppDelegate.m */; };
		68E26B5621CE924700F91182 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 68E26B5521CE924700F91182 /* ViewController.m */; };
		68E26B5921CE924700F91182 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 68E26B5721CE924700F91182 /* Main.storyboard */; };
		68E26B5B21CE924800F91182 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 68E26B5A21CE924800F91182 /* Assets.xcassets */; };
		68E26B5E21CE924800F91182 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 68E26B5C21CE924800F91182 /* LaunchScreen.storyboard */; };
		68E26B6121CE924800F91182 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 68E26B6021CE924800F91182 /* main.m */; };
		68FFE575273672AF008E323F /* KJBannerView.podspec in Resources */ = {isa = PBXBuildFile; fileRef = 68FFE573273672AE008E323F /* KJBannerView.podspec */; };
		68FFE576273672AF008E323F /* CHANGELOG.md in Resources */ = {isa = PBXBuildFile; fileRef = 68FFE574273672AE008E323F /* CHANGELOG.md */; };
		68FFE59927367754008E323F /* KJBannerView.m in Sources */ = {isa = PBXBuildFile; fileRef = 68FFE57E27367754008E323F /* KJBannerView.m */; };
		68FFE59C27367754008E323F /* KJBannerViewTimer.m in Sources */ = {isa = PBXBuildFile; fileRef = 68FFE58227367754008E323F /* KJBannerViewTimer.m */; };
		68FFE59D27367754008E323F /* KJBannerViewFlowLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 68FFE58327367754008E323F /* KJBannerViewFlowLayout.m */; };
		68FFE59E27367754008E323F /* KJBannerViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 68FFE58627367754008E323F /* KJBannerViewCell.m */; };
		68FFE59F27367754008E323F /* KJBannerView.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 68FFE58827367754008E323F /* KJBannerView.bundle */; };
		68FFE5A027367754008E323F /* KJWebImageDownloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 68FFE58B27367754008E323F /* KJWebImageDownloader.m */; };
		68FFE5A127367754008E323F /* UIView+KJWebImage.m in Sources */ = {isa = PBXBuildFile; fileRef = 68FFE59127367754008E323F /* UIView+KJWebImage.m */; };
		68FFE5A227367754008E323F /* KJImageCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 68FFE59227367754008E323F /* KJImageCache.m */; };
		68FFE5A327367754008E323F /* KJNetworkManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 68FFE59327367754008E323F /* KJNetworkManager.m */; };
		68FFE5A427367754008E323F /* KJAutoPurgingCache.m in Sources */ = {isa = PBXBuildFile; fileRef = 68FFE59427367754008E323F /* KJAutoPurgingCache.m */; };
		68FFE5A527367754008E323F /* KJPageControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 68FFE59727367754008E323F /* KJPageControl.m */; };
		68FFE5AC2736918F008E323F /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 68FFE5AB2736918F008E323F /* README.md */; };
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
		684059DB21EA08D00092F630 /* KJBannerModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KJBannerModel.h; sourceTree = "<group>"; };
		684059DC21EA08D00092F630 /* KJBannerModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KJBannerModel.m; sourceTree = "<group>"; };
		684059DE21EB59DA0092F630 /* KJCollectionViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KJCollectionViewCell.h; sourceTree = "<group>"; };
		684059DF21EB59DA0092F630 /* KJCollectionViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KJCollectionViewCell.m; sourceTree = "<group>"; };
		686568C726FB5EDC0001C691 /* DownloadViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DownloadViewController.m; sourceTree = "<group>"; };
		686568C826FB5EDC0001C691 /* KJViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KJViewModel.h; sourceTree = "<group>"; };
		686568C926FB5EDC0001C691 /* KJViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KJViewModel.m; sourceTree = "<group>"; };
		686568CA26FB5EDC0001C691 /* DownloadViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DownloadViewController.h; sourceTree = "<group>"; };
		6868EC0826FB5D54001F2400 /* MASCompositeConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASCompositeConstraint.h; sourceTree = "<group>"; };
		6868EC0926FB5D54001F2400 /* NSLayoutConstraint+MASDebugAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSLayoutConstraint+MASDebugAdditions.m"; sourceTree = "<group>"; };
		6868EC0A26FB5D54001F2400 /* MASConstraint+Private.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "MASConstraint+Private.h"; sourceTree = "<group>"; };
		6868EC0B26FB5D54001F2400 /* MASLayoutConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASLayoutConstraint.h; sourceTree = "<group>"; };
		6868EC0C26FB5D54001F2400 /* NSArray+MASShorthandAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+MASShorthandAdditions.h"; sourceTree = "<group>"; };
		6868EC0D26FB5D54001F2400 /* MASConstraintMaker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASConstraintMaker.h; sourceTree = "<group>"; };
		6868EC0E26FB5D54001F2400 /* View+MASAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "View+MASAdditions.h"; sourceTree = "<group>"; };
		6868EC0F26FB5D54001F2400 /* NSArray+MASAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+MASAdditions.h"; sourceTree = "<group>"; };
		6868EC1026FB5D54001F2400 /* MASUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASUtilities.h; sourceTree = "<group>"; };
		6868EC1126FB5D54001F2400 /* MASViewAttribute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASViewAttribute.h; sourceTree = "<group>"; };
		6868EC1226FB5D54001F2400 /* ViewController+MASAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "ViewController+MASAdditions.m"; sourceTree = "<group>"; };
		6868EC1326FB5D54001F2400 /* MASViewConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASViewConstraint.h; sourceTree = "<group>"; };
		6868EC1426FB5D54001F2400 /* MASConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MASConstraint.h; sourceTree = "<group>"; };
		6868EC1526FB5D54001F2400 /* NSLayoutConstraint+MASDebugAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSLayoutConstraint+MASDebugAdditions.h"; sourceTree = "<group>"; };
		6868EC1626FB5D54001F2400 /* MASCompositeConstraint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASCompositeConstraint.m; sourceTree = "<group>"; };
		6868EC1726FB5D54001F2400 /* MASConstraintMaker.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASConstraintMaker.m; sourceTree = "<group>"; };
		6868EC1826FB5D54001F2400 /* MASLayoutConstraint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASLayoutConstraint.m; sourceTree = "<group>"; };
		6868EC1926FB5D54001F2400 /* NSArray+MASAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+MASAdditions.m"; sourceTree = "<group>"; };
		6868EC1A26FB5D54001F2400 /* View+MASAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "View+MASAdditions.m"; sourceTree = "<group>"; };
		6868EC1B26FB5D54001F2400 /* View+MASShorthandAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "View+MASShorthandAdditions.h"; sourceTree = "<group>"; };
		6868EC1C26FB5D54001F2400 /* Masonry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Masonry.h; sourceTree = "<group>"; };
		6868EC1D26FB5D54001F2400 /* MASConstraint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASConstraint.m; sourceTree = "<group>"; };
		6868EC1E26FB5D54001F2400 /* ViewController+MASAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ViewController+MASAdditions.h"; sourceTree = "<group>"; };
		6868EC1F26FB5D54001F2400 /* MASViewConstraint.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASViewConstraint.m; sourceTree = "<group>"; };
		6868EC2026FB5D54001F2400 /* MASViewAttribute.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MASViewAttribute.m; sourceTree = "<group>"; };
		68BD69F72580712000D4B3AF /* IMG_0139.GIF */ = {isa = PBXFileReference; lastKnownFileType = image.gif; path = IMG_0139.GIF; sourceTree = "<group>"; };
		68E26B4E21CE924700F91182 /* KJBannerViewDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KJBannerViewDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
		68E26B5121CE924700F91182 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
		68E26B5221CE924700F91182 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
		68E26B5421CE924700F91182 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = "<group>"; };
		68E26B5521CE924700F91182 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = "<group>"; };
		68E26B5821CE924700F91182 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
		68E26B5A21CE924800F91182 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
		68E26B5D21CE924800F91182 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
		68E26B5F21CE924800F91182 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
		68E26B6021CE924800F91182 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
		68FFE573273672AE008E323F /* KJBannerView.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; path = KJBannerView.podspec; sourceTree = SOURCE_ROOT; };
		68FFE574273672AE008E323F /* CHANGELOG.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = CHANGELOG.md; sourceTree = SOURCE_ROOT; };
		68FFE57C27367754008E323F /* KJBannerViewTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KJBannerViewTimer.h; sourceTree = "<group>"; };
		68FFE57D27367754008E323F /* KJBannerViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KJBannerViewCell.h; sourceTree = "<group>"; };
		68FFE57E27367754008E323F /* KJBannerView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KJBannerView.m; sourceTree = "<group>"; };
		68FFE58027367754008E323F /* KJBannerViewFlowLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KJBannerViewFlowLayout.h; sourceTree = "<group>"; };
		68FFE58227367754008E323F /* KJBannerViewTimer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KJBannerViewTimer.m; sourceTree = "<group>"; };
		68FFE58327367754008E323F /* KJBannerViewFlowLayout.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KJBannerViewFlowLayout.m; sourceTree = "<group>"; };
		68FFE58527367754008E323F /* KJBannerView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KJBannerView.h; sourceTree = "<group>"; };
		68FFE58627367754008E323F /* KJBannerViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KJBannerViewCell.m; sourceTree = "<group>"; };
		68FFE58827367754008E323F /* KJBannerView.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = KJBannerView.bundle; sourceTree = "<group>"; };
		68FFE58A27367754008E323F /* UIView+KJWebImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIView+KJWebImage.h"; sourceTree = "<group>"; };
		68FFE58B27367754008E323F /* KJWebImageDownloader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KJWebImageDownloader.m; sourceTree = "<group>"; };
		68FFE58C27367754008E323F /* KJImageCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KJImageCache.h; sourceTree = "<group>"; };
		68FFE58D27367754008E323F /* KJAutoPurgingCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KJAutoPurgingCache.h; sourceTree = "<group>"; };
		68FFE58E27367754008E323F /* KJNetworkManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KJNetworkManager.h; sourceTree = "<group>"; };
		68FFE58F27367754008E323F /* KJWebImageDownloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KJWebImageDownloader.h; sourceTree = "<group>"; };
		68FFE59127367754008E323F /* UIView+KJWebImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+KJWebImage.m"; sourceTree = "<group>"; };
		68FFE59227367754008E323F /* KJImageCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KJImageCache.m; sourceTree = "<group>"; };
		68FFE59327367754008E323F /* KJNetworkManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KJNetworkManager.m; sourceTree = "<group>"; };
		68FFE59427367754008E323F /* KJAutoPurgingCache.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KJAutoPurgingCache.m; sourceTree = "<group>"; };
		68FFE59627367754008E323F /* KJPageControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KJPageControl.h; sourceTree = "<group>"; };
		68FFE59727367754008E323F /* KJPageControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KJPageControl.m; sourceTree = "<group>"; };
		68FFE59827367754008E323F /* KJBannerHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KJBannerHeader.h; sourceTree = "<group>"; };
		68FFE5AA273686ED008E323F /* KJWebImageHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KJWebImageHeader.h; sourceTree = "<group>"; };
		68FFE5AB2736918F008E323F /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = SOURCE_ROOT; };
/* End PBXFileReference section */

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

/* Begin PBXGroup section */
		06EFFDA7C3924E99F02B4C94 /* Frameworks */ = {
			isa = PBXGroup;
			children = (
			);
			name = Frameworks;
			sourceTree = "<group>";
		};
		6868EC0726FB5D54001F2400 /* Masonry */ = {
			isa = PBXGroup;
			children = (
				6868EC0826FB5D54001F2400 /* MASCompositeConstraint.h */,
				6868EC1626FB5D54001F2400 /* MASCompositeConstraint.m */,
				6868EC1426FB5D54001F2400 /* MASConstraint.h */,
				6868EC1D26FB5D54001F2400 /* MASConstraint.m */,
				6868EC0A26FB5D54001F2400 /* MASConstraint+Private.h */,
				6868EC0D26FB5D54001F2400 /* MASConstraintMaker.h */,
				6868EC1726FB5D54001F2400 /* MASConstraintMaker.m */,
				6868EC0B26FB5D54001F2400 /* MASLayoutConstraint.h */,
				6868EC1826FB5D54001F2400 /* MASLayoutConstraint.m */,
				6868EC1C26FB5D54001F2400 /* Masonry.h */,
				6868EC1026FB5D54001F2400 /* MASUtilities.h */,
				6868EC1126FB5D54001F2400 /* MASViewAttribute.h */,
				6868EC2026FB5D54001F2400 /* MASViewAttribute.m */,
				6868EC1326FB5D54001F2400 /* MASViewConstraint.h */,
				6868EC1F26FB5D54001F2400 /* MASViewConstraint.m */,
				6868EC0F26FB5D54001F2400 /* NSArray+MASAdditions.h */,
				6868EC1926FB5D54001F2400 /* NSArray+MASAdditions.m */,
				6868EC0C26FB5D54001F2400 /* NSArray+MASShorthandAdditions.h */,
				6868EC1526FB5D54001F2400 /* NSLayoutConstraint+MASDebugAdditions.h */,
				6868EC0926FB5D54001F2400 /* NSLayoutConstraint+MASDebugAdditions.m */,
				6868EC0E26FB5D54001F2400 /* View+MASAdditions.h */,
				6868EC1A26FB5D54001F2400 /* View+MASAdditions.m */,
				6868EC1B26FB5D54001F2400 /* View+MASShorthandAdditions.h */,
				6868EC1E26FB5D54001F2400 /* ViewController+MASAdditions.h */,
				6868EC1226FB5D54001F2400 /* ViewController+MASAdditions.m */,
			);
			path = Masonry;
			sourceTree = "<group>";
		};
		68E26B4521CE924700F91182 = {
			isa = PBXGroup;
			children = (
				68E26B5021CE924700F91182 /* KJBannerViewDemo */,
				68E26B4F21CE924700F91182 /* Products */,
				06EFFDA7C3924E99F02B4C94 /* Frameworks */,
			);
			sourceTree = "<group>";
		};
		68E26B4F21CE924700F91182 /* Products */ = {
			isa = PBXGroup;
			children = (
				68E26B4E21CE924700F91182 /* KJBannerViewDemo.app */,
			);
			name = Products;
			sourceTree = "<group>";
		};
		68E26B5021CE924700F91182 /* KJBannerViewDemo */ = {
			isa = PBXGroup;
			children = (
				68E26B5121CE924700F91182 /* AppDelegate.h */,
				68E26B5221CE924700F91182 /* AppDelegate.m */,
				6868EC0726FB5D54001F2400 /* Masonry */,
				68FFE56E27367023008E323F /* Modules */,
				68FFE5702736719E008E323F /* Resources */,
				68FFE57A27367754008E323F /* Sources */,
				68FFE5722736725D008E323F /* Supporting Files */,
			);
			path = KJBannerViewDemo;
			sourceTree = "<group>";
		};
		68FFE56E27367023008E323F /* Modules */ = {
			isa = PBXGroup;
			children = (
				68FFE5A6273678C1008E323F /* Controller */,
				68FFE5A7273678F8008E323F /* Model */,
				68FFE5A8273678FF008E323F /* View */,
				68FFE5A927367908008E323F /* ViewModel */,
			);
			path = Modules;
			sourceTree = "<group>";
		};
		68FFE5702736719E008E323F /* Resources */ = {
			isa = PBXGroup;
			children = (
				68BD69F72580712000D4B3AF /* IMG_0139.GIF */,
			);
			path = Resources;
			sourceTree = "<group>";
		};
		68FFE5722736725D008E323F /* Supporting Files */ = {
			isa = PBXGroup;
			children = (
				68E26B5A21CE924800F91182 /* Assets.xcassets */,
				68FFE574273672AE008E323F /* CHANGELOG.md */,
				68E26B5F21CE924800F91182 /* Info.plist */,
				68FFE573273672AE008E323F /* KJBannerView.podspec */,
				68E26B5C21CE924800F91182 /* LaunchScreen.storyboard */,
				68E26B6021CE924800F91182 /* main.m */,
				68E26B5721CE924700F91182 /* Main.storyboard */,
				68FFE5AB2736918F008E323F /* README.md */,
			);
			path = "Supporting Files";
			sourceTree = "<group>";
		};
		68FFE57A27367754008E323F /* Sources */ = {
			isa = PBXGroup;
			children = (
				68FFE59827367754008E323F /* KJBannerHeader.h */,
				68FFE57B27367754008E323F /* KJBannerView */,
				68FFE59527367754008E323F /* PageControl */,
				68FFE58927367754008E323F /* WebImage */,
			);
			path = Sources;
			sourceTree = SOURCE_ROOT;
		};
		68FFE57B27367754008E323F /* KJBannerView */ = {
			isa = PBXGroup;
			children = (
				68FFE58827367754008E323F /* KJBannerView.bundle */,
				68FFE58527367754008E323F /* KJBannerView.h */,
				68FFE57E27367754008E323F /* KJBannerView.m */,
				68FFE57D27367754008E323F /* KJBannerViewCell.h */,
				68FFE58627367754008E323F /* KJBannerViewCell.m */,
				68FFE58027367754008E323F /* KJBannerViewFlowLayout.h */,
				68FFE58327367754008E323F /* KJBannerViewFlowLayout.m */,
				68FFE57C27367754008E323F /* KJBannerViewTimer.h */,
				68FFE58227367754008E323F /* KJBannerViewTimer.m */,
			);
			path = KJBannerView;
			sourceTree = "<group>";
		};
		68FFE58927367754008E323F /* WebImage */ = {
			isa = PBXGroup;
			children = (
				68FFE58D27367754008E323F /* KJAutoPurgingCache.h */,
				68FFE59427367754008E323F /* KJAutoPurgingCache.m */,
				68FFE5AA273686ED008E323F /* KJWebImageHeader.h */,
				68FFE58C27367754008E323F /* KJImageCache.h */,
				68FFE59227367754008E323F /* KJImageCache.m */,
				68FFE58E27367754008E323F /* KJNetworkManager.h */,
				68FFE59327367754008E323F /* KJNetworkManager.m */,
				68FFE58F27367754008E323F /* KJWebImageDownloader.h */,
				68FFE58B27367754008E323F /* KJWebImageDownloader.m */,
				68FFE58A27367754008E323F /* UIView+KJWebImage.h */,
				68FFE59127367754008E323F /* UIView+KJWebImage.m */,
			);
			path = WebImage;
			sourceTree = "<group>";
		};
		68FFE59527367754008E323F /* PageControl */ = {
			isa = PBXGroup;
			children = (
				68FFE59627367754008E323F /* KJPageControl.h */,
				68FFE59727367754008E323F /* KJPageControl.m */,
			);
			path = PageControl;
			sourceTree = "<group>";
		};
		68FFE5A6273678C1008E323F /* Controller */ = {
			isa = PBXGroup;
			children = (
				686568CA26FB5EDC0001C691 /* DownloadViewController.h */,
				686568C726FB5EDC0001C691 /* DownloadViewController.m */,
				68E26B5421CE924700F91182 /* ViewController.h */,
				68E26B5521CE924700F91182 /* ViewController.m */,
			);
			path = Controller;
			sourceTree = "<group>";
		};
		68FFE5A7273678F8008E323F /* Model */ = {
			isa = PBXGroup;
			children = (
				684059DB21EA08D00092F630 /* KJBannerModel.h */,
				684059DC21EA08D00092F630 /* KJBannerModel.m */,
			);
			path = Model;
			sourceTree = "<group>";
		};
		68FFE5A8273678FF008E323F /* View */ = {
			isa = PBXGroup;
			children = (
				684059DE21EB59DA0092F630 /* KJCollectionViewCell.h */,
				684059DF21EB59DA0092F630 /* KJCollectionViewCell.m */,
			);
			path = View;
			sourceTree = "<group>";
		};
		68FFE5A927367908008E323F /* ViewModel */ = {
			isa = PBXGroup;
			children = (
				686568C826FB5EDC0001C691 /* KJViewModel.h */,
				686568C926FB5EDC0001C691 /* KJViewModel.m */,
			);
			path = ViewModel;
			sourceTree = "<group>";
		};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
		68E26B4D21CE924700F91182 /* KJBannerViewDemo */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = 68E26B6421CE924800F91182 /* Build configuration list for PBXNativeTarget "KJBannerViewDemo" */;
			buildPhases = (
				68E26B4A21CE924700F91182 /* Sources */,
				68E26B4B21CE924700F91182 /* Frameworks */,
				68E26B4C21CE924700F91182 /* Resources */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = KJBannerViewDemo;
			productName = KJBannerViewDemo;
			productReference = 68E26B4E21CE924700F91182 /* KJBannerViewDemo.app */;
			productType = "com.apple.product-type.application";
		};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
		68E26B4621CE924700F91182 /* Project object */ = {
			isa = PBXProject;
			attributes = {
				LastUpgradeCheck = 1220;
				ORGANIZATIONNAME = "杨科军";
				TargetAttributes = {
					68E26B4D21CE924700F91182 = {
						CreatedOnToolsVersion = 10.1;
					};
				};
			};
			buildConfigurationList = 68E26B4921CE924700F91182 /* Build configuration list for PBXProject "KJBannerViewDemo" */;
			compatibilityVersion = "Xcode 9.3";
			developmentRegion = en;
			hasScannedForEncodings = 0;
			knownRegions = (
				en,
				Base,
			);
			mainGroup = 68E26B4521CE924700F91182;
			productRefGroup = 68E26B4F21CE924700F91182 /* Products */;
			projectDirPath = "";
			projectRoot = "";
			targets = (
				68E26B4D21CE924700F91182 /* KJBannerViewDemo */,
			);
		};
/* End PBXProject section */

/* Begin PBXResourcesBuildPhase section */
		68E26B4C21CE924700F91182 /* Resources */ = {
			isa = PBXResourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				68FFE575273672AF008E323F /* KJBannerView.podspec in Resources */,
				68E26B5E21CE924800F91182 /* LaunchScreen.storyboard in Resources */,
				68E26B5B21CE924800F91182 /* Assets.xcassets in Resources */,
				68E26B5921CE924700F91182 /* Main.storyboard in Resources */,
				68FFE576273672AF008E323F /* CHANGELOG.md in Resources */,
				68FFE59F27367754008E323F /* KJBannerView.bundle in Resources */,
				68FFE5AC2736918F008E323F /* README.md in Resources */,
				68BD69F82580712000D4B3AF /* IMG_0139.GIF in Resources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXResourcesBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
		68E26B4A21CE924700F91182 /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				6868EC2426FB5D54001F2400 /* MASConstraintMaker.m in Sources */,
				686568CB26FB5EDC0001C691 /* DownloadViewController.m in Sources */,
				68E26B5621CE924700F91182 /* ViewController.m in Sources */,
				68E26B6121CE924800F91182 /* main.m in Sources */,
				686568CC26FB5EDC0001C691 /* KJViewModel.m in Sources */,
				6868EC2326FB5D54001F2400 /* MASCompositeConstraint.m in Sources */,
				6868EC2826FB5D54001F2400 /* MASConstraint.m in Sources */,
				6868EC2726FB5D54001F2400 /* View+MASAdditions.m in Sources */,
				68E26B5321CE924700F91182 /* AppDelegate.m in Sources */,
				68FFE5A227367754008E323F /* KJImageCache.m in Sources */,
				68FFE5A127367754008E323F /* UIView+KJWebImage.m in Sources */,
				68FFE59927367754008E323F /* KJBannerView.m in Sources */,
				6868EC2526FB5D54001F2400 /* MASLayoutConstraint.m in Sources */,
				6868EC2926FB5D54001F2400 /* MASViewConstraint.m in Sources */,
				68FFE5A027367754008E323F /* KJWebImageDownloader.m in Sources */,
				684059DD21EA08D00092F630 /* KJBannerModel.m in Sources */,
				68FFE5A327367754008E323F /* KJNetworkManager.m in Sources */,
				6868EC2626FB5D54001F2400 /* NSArray+MASAdditions.m in Sources */,
				68FFE5A427367754008E323F /* KJAutoPurgingCache.m in Sources */,
				68FFE59E27367754008E323F /* KJBannerViewCell.m in Sources */,
				68FFE5A527367754008E323F /* KJPageControl.m in Sources */,
				6868EC2126FB5D54001F2400 /* NSLayoutConstraint+MASDebugAdditions.m in Sources */,
				68FFE59D27367754008E323F /* KJBannerViewFlowLayout.m in Sources */,
				6868EC2226FB5D54001F2400 /* ViewController+MASAdditions.m in Sources */,
				684059E121EB59DA0092F630 /* KJCollectionViewCell.m in Sources */,
				68FFE59C27367754008E323F /* KJBannerViewTimer.m in Sources */,
				6868EC2A26FB5D54001F2400 /* MASViewAttribute.m in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXSourcesBuildPhase section */

/* Begin PBXVariantGroup section */
		68E26B5721CE924700F91182 /* Main.storyboard */ = {
			isa = PBXVariantGroup;
			children = (
				68E26B5821CE924700F91182 /* Base */,
			);
			name = Main.storyboard;
			sourceTree = "<group>";
		};
		68E26B5C21CE924800F91182 /* LaunchScreen.storyboard */ = {
			isa = PBXVariantGroup;
			children = (
				68E26B5D21CE924800F91182 /* Base */,
			);
			name = LaunchScreen.storyboard;
			sourceTree = "<group>";
		};
/* End PBXVariantGroup section */

/* Begin XCBuildConfiguration section */
		68E26B6221CE924800F91182 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ALWAYS_SEARCH_USER_PATHS = NO;
				CLANG_ANALYZER_NONNULL = YES;
				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
				CLANG_CXX_LIBRARY = "libc++";
				CLANG_ENABLE_MODULES = YES;
				CLANG_ENABLE_OBJC_ARC = YES;
				CLANG_ENABLE_OBJC_WEAK = YES;
				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
				CLANG_WARN_BOOL_CONVERSION = YES;
				CLANG_WARN_COMMA = YES;
				CLANG_WARN_CONSTANT_CONVERSION = YES;
				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = 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_NON_LITERAL_NULL_CONVERSION = YES;
				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
				CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
				CLANG_WARN_STRICT_PROTOTYPES = YES;
				CLANG_WARN_SUSPICIOUS_MOVE = YES;
				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
				CLANG_WARN_UNREACHABLE_CODE = YES;
				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
				CODE_SIGN_IDENTITY = "iPhone Developer";
				COPY_PHASE_STRIP = NO;
				DEBUG_INFORMATION_FORMAT = dwarf;
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				ENABLE_TESTABILITY = YES;
				GCC_C_LANGUAGE_STANDARD = gnu11;
				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 = 12.1;
				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
				MTL_FAST_MATH = YES;
				ONLY_ACTIVE_ARCH = YES;
				SDKROOT = iphoneos;
			};
			name = Debug;
		};
		68E26B6321CE924800F91182 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ALWAYS_SEARCH_USER_PATHS = NO;
				CLANG_ANALYZER_NONNULL = YES;
				CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
				CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
				CLANG_CXX_LIBRARY = "libc++";
				CLANG_ENABLE_MODULES = YES;
				CLANG_ENABLE_OBJC_ARC = YES;
				CLANG_ENABLE_OBJC_WEAK = YES;
				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
				CLANG_WARN_BOOL_CONVERSION = YES;
				CLANG_WARN_COMMA = YES;
				CLANG_WARN_CONSTANT_CONVERSION = YES;
				CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = 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_NON_LITERAL_NULL_CONVERSION = YES;
				CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
				CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
				CLANG_WARN_STRICT_PROTOTYPES = YES;
				CLANG_WARN_SUSPICIOUS_MOVE = YES;
				CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
				CLANG_WARN_UNREACHABLE_CODE = YES;
				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
				CODE_SIGN_IDENTITY = "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 = gnu11;
				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 = 12.1;
				MTL_ENABLE_DEBUG_INFO = NO;
				MTL_FAST_MATH = YES;
				SDKROOT = iphoneos;
				VALIDATE_PRODUCT = YES;
			};
			name = Release;
		};
		68E26B6521CE924800F91182 /* Debug */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
				CODE_SIGN_STYLE = Automatic;
				DEVELOPMENT_TEAM = 66T6NB6T4J;
				INFOPLIST_FILE = "KJBannerViewDemo/Supporting Files/Info.plist";
				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
				LD_RUNPATH_SEARCH_PATHS = (
					"$(inherited)",
					"@executable_path/Frameworks",
				);
				PRODUCT_BUNDLE_IDENTIFIER = com.yangkejun.KJBannerViewDemo;
				PRODUCT_NAME = "$(TARGET_NAME)";
				TARGETED_DEVICE_FAMILY = "1,2";
			};
			name = Debug;
		};
		68E26B6621CE924800F91182 /* Release */ = {
			isa = XCBuildConfiguration;
			buildSettings = {
				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
				CODE_SIGN_STYLE = Automatic;
				DEVELOPMENT_TEAM = 66T6NB6T4J;
				INFOPLIST_FILE = "KJBannerViewDemo/Supporting Files/Info.plist";
				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
				LD_RUNPATH_SEARCH_PATHS = (
					"$(inherited)",
					"@executable_path/Frameworks",
				);
				PRODUCT_BUNDLE_IDENTIFIER = com.yangkejun.KJBannerViewDemo;
				PRODUCT_NAME = "$(TARGET_NAME)";
				TARGETED_DEVICE_FAMILY = "1,2";
			};
			name = Release;
		};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
		68E26B4921CE924700F91182 /* Build configuration list for PBXProject "KJBannerViewDemo" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				68E26B6221CE924800F91182 /* Debug */,
Download .txt
gitextract_0063ocvp/

├── .gitignore
├── CHANGELOG.md
├── KJBannerView.podspec
├── KJBannerViewDemo/
│   ├── AppDelegate.h
│   ├── AppDelegate.m
│   ├── Masonry/
│   │   ├── MASCompositeConstraint.h
│   │   ├── MASCompositeConstraint.m
│   │   ├── MASConstraint+Private.h
│   │   ├── MASConstraint.h
│   │   ├── MASConstraint.m
│   │   ├── MASConstraintMaker.h
│   │   ├── MASConstraintMaker.m
│   │   ├── MASLayoutConstraint.h
│   │   ├── MASLayoutConstraint.m
│   │   ├── MASUtilities.h
│   │   ├── MASViewAttribute.h
│   │   ├── MASViewAttribute.m
│   │   ├── MASViewConstraint.h
│   │   ├── MASViewConstraint.m
│   │   ├── Masonry.h
│   │   ├── NSArray+MASAdditions.h
│   │   ├── NSArray+MASAdditions.m
│   │   ├── NSArray+MASShorthandAdditions.h
│   │   ├── NSLayoutConstraint+MASDebugAdditions.h
│   │   ├── NSLayoutConstraint+MASDebugAdditions.m
│   │   ├── View+MASAdditions.h
│   │   ├── View+MASAdditions.m
│   │   ├── View+MASShorthandAdditions.h
│   │   ├── ViewController+MASAdditions.h
│   │   └── ViewController+MASAdditions.m
│   ├── Modules/
│   │   ├── Controller/
│   │   │   ├── DownloadViewController.h
│   │   │   ├── DownloadViewController.m
│   │   │   ├── ViewController.h
│   │   │   └── ViewController.m
│   │   ├── Model/
│   │   │   ├── KJBannerModel.h
│   │   │   └── KJBannerModel.m
│   │   ├── View/
│   │   │   ├── KJCollectionViewCell.h
│   │   │   └── KJCollectionViewCell.m
│   │   └── ViewModel/
│   │       ├── KJViewModel.h
│   │       └── KJViewModel.m
│   └── Supporting Files/
│       ├── Assets.xcassets/
│       │   ├── AppIcon.appiconset/
│       │   │   └── Contents.json
│       │   ├── Contents.json
│       │   ├── IMG_4931.imageset/
│       │   │   ├── Contents.json
│       │   │   ├── Contents.json~Add 2.0.3
│       │   │   ├── Contents.json~HEAD
│       │   │   ├── IMG_4931.jpg~Add 2.0.3
│       │   │   └── IMG_4931.jpg~HEAD
│       │   ├── IMG_Guitar_52.imageset/
│       │   │   └── Contents.json
│       │   ├── ax.imageset/
│       │   │   └── Contents.json
│       │   └── z_ds.imageset/
│       │       └── Contents.json
│       ├── Base.lproj/
│       │   ├── LaunchScreen.storyboard
│       │   └── Main.storyboard
│       ├── Info.plist
│       └── main.m
├── KJBannerViewDemo.xcodeproj/
│   ├── project.pbxproj
│   ├── project.xcworkspace/
│   │   ├── contents.xcworkspacedata
│   │   └── xcshareddata/
│   │       └── IDEWorkspaceChecks.plist
│   └── xcshareddata/
│       └── xcschemes/
│           └── KJBannerViewDemo.xcscheme
├── LICENSE
├── README.md
└── Sources/
    ├── KJBannerHeader.h
    ├── KJBannerView/
    │   ├── KJBannerView.h
    │   ├── KJBannerView.m
    │   ├── KJBannerViewCell.h
    │   ├── KJBannerViewCell.m
    │   ├── KJBannerViewFlowLayout.h
    │   ├── KJBannerViewFlowLayout.m
    │   ├── KJBannerViewTimer.h
    │   └── KJBannerViewTimer.m
    ├── PageControl/
    │   ├── KJPageControl.h
    │   └── KJPageControl.m
    └── WebImage/
        ├── KJAutoPurgingCache.h
        ├── KJAutoPurgingCache.m
        ├── KJImageCache.h
        ├── KJImageCache.m
        ├── KJNetworkManager.h
        ├── KJNetworkManager.m
        ├── KJWebImageDownloader.h
        ├── KJWebImageDownloader.m
        ├── KJWebImageHeader.h
        ├── UIView+KJWebImage.h
        └── UIView+KJWebImage.m
Download .txt
SYMBOL INDEX (8 symbols across 3 files)

FILE: KJBannerViewDemo/Masonry/MASUtilities.h
  type UILayoutPriority (line 20) | typedef UILayoutPriority MASLayoutPriority;
  type NSLayoutPriority (line 33) | typedef NSLayoutPriority MASLayoutPriority;
  function id (line 76) | static inline id _MASBoxValue(const char *type, ...) {

FILE: KJBannerViewDemo/Masonry/NSArray+MASAdditions.h
  type MASAxisTypeHorizontal (line 13) | typedef NS_ENUM(NSUInteger, MASAxisType) {

FILE: KJBannerViewDemo/Masonry/View+MASShorthandAdditions.h
  function implementation (line 72) | implementation MAS_VIEW (MASShorthandAdditions)
  function block (line 119) | void(NS_NOESCAPE ^)(MASConstraintMaker *))block {
  function block (line 123) | void(NS_NOESCAPE ^)(MASConstraintMaker *))block {
  function block (line 127) | void(NS_NOESCAPE ^)(MASConstraintMaker *))block {
Condensed preview — 82 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (318K chars).
[
  {
    "path": ".gitignore",
    "chars": 1665,
    "preview": "# Xcode\n#\n# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore\n\n"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 5471,
    "preview": "# <a id=\"功能介绍\"></a>功能介绍\nKJBannerView 是一款轮播Banner,支持gif和url混播,自带图片下载和缓存    \n1. 缩放无限自动循环滚动  √    \n2. 支持四种方向滚动,从左往右、从右往左、从上"
  },
  {
    "path": "KJBannerView.podspec",
    "chars": 1063,
    "preview": "Pod::Spec.new do |s|\n  s.name         = \"KJBannerView\"\n  s.version      = \"3.1.0\"\n  s.summary      = \"KJBannerView是一款自带图"
  },
  {
    "path": "KJBannerViewDemo/AppDelegate.h",
    "chars": 317,
    "preview": "//\n//  AppDelegate.h\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2018/12/22.\n//  Copyright © 2018 杨科军. All rights rese"
  },
  {
    "path": "KJBannerViewDemo/AppDelegate.m",
    "chars": 2229,
    "preview": "//\n//  AppDelegate.m\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2018/12/22.\n//  Copyright © 2018 杨科军. All rights rese"
  },
  {
    "path": "KJBannerViewDemo/Masonry/MASCompositeConstraint.h",
    "chars": 494,
    "preview": "//\n//  MASCompositeConstraint.h\n//  Masonry\n//\n//  Created by Jonas Budelmann on 21/07/13.\n//  Copyright (c) 2013 cloudl"
  },
  {
    "path": "KJBannerViewDemo/Masonry/MASCompositeConstraint.m",
    "chars": 4870,
    "preview": "//\n//  MASCompositeConstraint.m\n//  Masonry\n//\n//  Created by Jonas Budelmann on 21/07/13.\n//  Copyright (c) 2013 cloudl"
  },
  {
    "path": "KJBannerViewDemo/Masonry/MASConstraint+Private.h",
    "chars": 1785,
    "preview": "//\n//  MASConstraint+Private.h\n//  Masonry\n//\n//  Created by Nick Tymchenko on 29/04/14.\n//  Copyright (c) 2014 cloudlin"
  },
  {
    "path": "KJBannerViewDemo/Masonry/MASConstraint.h",
    "chars": 7872,
    "preview": "//\n//  MASConstraint.h\n//  Masonry\n//\n//  Created by Jonas Budelmann on 22/07/13.\n//  Copyright (c) 2013 cloudling. All "
  },
  {
    "path": "KJBannerViewDemo/Masonry/MASConstraint.m",
    "chars": 8233,
    "preview": "//\n//  MASConstraint.m\n//  Masonry\n//\n//  Created by Nick Tymchenko on 1/20/14.\n//\n\n#import \"MASConstraint.h\"\n#import \"M"
  },
  {
    "path": "KJBannerViewDemo/Masonry/MASConstraintMaker.h",
    "chars": 5734,
    "preview": "//\n//  MASConstraintMaker.h\n//  Masonry\n//\n//  Created by Jonas Budelmann on 20/07/13.\n//  Copyright (c) 2013 cloudling."
  },
  {
    "path": "KJBannerViewDemo/Masonry/MASConstraintMaker.m",
    "chars": 10450,
    "preview": "//\n//  MASConstraintMaker.m\n//  Masonry\n//\n//  Created by Jonas Budelmann on 20/07/13.\n//  Copyright (c) 2013 cloudling."
  },
  {
    "path": "KJBannerViewDemo/Masonry/MASLayoutConstraint.h",
    "chars": 505,
    "preview": "//\n//  MASLayoutConstraint.h\n//  Masonry\n//\n//  Created by Jonas Budelmann on 3/08/13.\n//  Copyright (c) 2013 Jonas Bude"
  },
  {
    "path": "KJBannerViewDemo/Masonry/MASLayoutConstraint.m",
    "chars": 227,
    "preview": "//\n//  MASLayoutConstraint.m\n//  Masonry\n//\n//  Created by Jonas Budelmann on 3/08/13.\n//  Copyright (c) 2013 Jonas Bude"
  },
  {
    "path": "KJBannerViewDemo/Masonry/MASUtilities.h",
    "chars": 6273,
    "preview": "//\n//  MASUtilities.h\n//  Masonry\n//\n//  Created by Jonas Budelmann on 19/08/13.\n//  Copyright (c) 2013 Jonas Budelmann."
  },
  {
    "path": "KJBannerViewDemo/Masonry/MASViewAttribute.h",
    "chars": 1221,
    "preview": "//\n//  MASViewAttribute.h\n//  Masonry\n//\n//  Created by Jonas Budelmann on 21/07/13.\n//  Copyright (c) 2013 cloudling. A"
  },
  {
    "path": "KJBannerViewDemo/Masonry/MASViewAttribute.m",
    "chars": 1195,
    "preview": "//\n//  MASViewAttribute.m\n//  Masonry\n//\n//  Created by Jonas Budelmann on 21/07/13.\n//  Copyright (c) 2013 cloudling. A"
  },
  {
    "path": "KJBannerViewDemo/Masonry/MASViewConstraint.h",
    "chars": 1279,
    "preview": "//\n//  MASViewConstraint.h\n//  Masonry\n//\n//  Created by Jonas Budelmann on 20/07/13.\n//  Copyright (c) 2013 cloudling. "
  },
  {
    "path": "KJBannerViewDemo/Masonry/MASViewConstraint.m",
    "chars": 13358,
    "preview": "//\n//  MASViewConstraint.m\n//  Masonry\n//\n//  Created by Jonas Budelmann on 20/07/13.\n//  Copyright (c) 2013 cloudling. "
  },
  {
    "path": "KJBannerViewDemo/Masonry/Masonry.h",
    "chars": 802,
    "preview": "//\n//  Masonry.h\n//  Masonry\n//\n//  Created by Jonas Budelmann on 20/07/13.\n//  Copyright (c) 2013 cloudling. All rights"
  },
  {
    "path": "KJBannerViewDemo/Masonry/NSArray+MASAdditions.h",
    "chars": 2789,
    "preview": "//\n//  NSArray+MASAdditions.h\n//\n//\n//  Created by Daniel Hammond on 11/26/13.\n//\n//\n\n#import \"MASUtilities.h\"\n#import \""
  },
  {
    "path": "KJBannerViewDemo/Masonry/NSArray+MASAdditions.m",
    "chars": 6154,
    "preview": "//\n//  NSArray+MASAdditions.m\n//  \n//\n//  Created by Daniel Hammond on 11/26/13.\n//\n//\n\n#import \"NSArray+MASAdditions.h\""
  },
  {
    "path": "KJBannerViewDemo/Masonry/NSArray+MASShorthandAdditions.h",
    "chars": 1016,
    "preview": "//\n//  NSArray+MASShorthandAdditions.h\n//  Masonry\n//\n//  Created by Jonas Budelmann on 22/07/13.\n//  Copyright (c) 2013"
  },
  {
    "path": "KJBannerViewDemo/Masonry/NSLayoutConstraint+MASDebugAdditions.h",
    "chars": 326,
    "preview": "//\n//  NSLayoutConstraint+MASDebugAdditions.h\n//  Masonry\n//\n//  Created by Jonas Budelmann on 3/08/13.\n//  Copyright (c"
  },
  {
    "path": "KJBannerViewDemo/Masonry/NSLayoutConstraint+MASDebugAdditions.m",
    "chars": 5771,
    "preview": "//\n//  NSLayoutConstraint+MASDebugAdditions.m\n//  Masonry\n//\n//  Created by Jonas Budelmann on 3/08/13.\n//  Copyright (c"
  },
  {
    "path": "KJBannerViewDemo/Masonry/View+MASAdditions.h",
    "chars": 4894,
    "preview": "//\n//  UIView+MASAdditions.h\n//  Masonry\n//\n//  Created by Jonas Budelmann on 20/07/13.\n//  Copyright (c) 2013 cloudling"
  },
  {
    "path": "KJBannerViewDemo/Masonry/View+MASAdditions.m",
    "chars": 6573,
    "preview": "//\n//  UIView+MASAdditions.m\n//  Masonry\n//\n//  Created by Jonas Budelmann on 20/07/13.\n//  Copyright (c) 2013 cloudling"
  },
  {
    "path": "KJBannerViewDemo/Masonry/View+MASShorthandAdditions.h",
    "chars": 4772,
    "preview": "//\n//  UIView+MASShorthandAdditions.h\n//  Masonry\n//\n//  Created by Jonas Budelmann on 22/07/13.\n//  Copyright (c) 2013 "
  },
  {
    "path": "KJBannerViewDemo/Masonry/ViewController+MASAdditions.h",
    "chars": 891,
    "preview": "//\n//  UIViewController+MASAdditions.h\n//  Masonry\n//\n//  Created by Craig Siemens on 2015-06-23.\n//\n//\n\n#import \"MASUti"
  },
  {
    "path": "KJBannerViewDemo/Masonry/ViewController+MASAdditions.m",
    "chars": 1302,
    "preview": "//\n//  UIViewController+MASAdditions.m\n//  Masonry\n//\n//  Created by Craig Siemens on 2015-06-23.\n//\n//\n\n#import \"ViewCo"
  },
  {
    "path": "KJBannerViewDemo/Modules/Controller/DownloadViewController.h",
    "chars": 316,
    "preview": "//\n//  DownloadViewController.h\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2020/1/15.\n//  Copyright © 2020 杨科军. All r"
  },
  {
    "path": "KJBannerViewDemo/Modules/Controller/DownloadViewController.m",
    "chars": 5298,
    "preview": "//\n//  DownloadViewController.m\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2020/1/15.\n//  Copyright © 2020 杨科军. All r"
  },
  {
    "path": "KJBannerViewDemo/Modules/Controller/ViewController.h",
    "chars": 255,
    "preview": "//\n//  ViewController.h\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2018/12/22.\n//  Copyright © 2018 杨科军. All rights r"
  },
  {
    "path": "KJBannerViewDemo/Modules/Controller/ViewController.m",
    "chars": 8372,
    "preview": "//\n//  ViewController.m\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2018/12/22.\n//  Copyright © 2018 杨科军. All rights r"
  },
  {
    "path": "KJBannerViewDemo/Modules/Model/KJBannerModel.h",
    "chars": 561,
    "preview": "//\n//  KJBannerModel.h\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2019/1/12.\n//  Copyright © 2019 杨科军. All rights res"
  },
  {
    "path": "KJBannerViewDemo/Modules/Model/KJBannerModel.m",
    "chars": 1040,
    "preview": "//\n//  KJBannerModel.m\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2019/1/12.\n//  Copyright © 2019 杨科军. All rights res"
  },
  {
    "path": "KJBannerViewDemo/Modules/View/KJCollectionViewCell.h",
    "chars": 391,
    "preview": "//\n//  KJCollectionViewCell.h\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2019/1/13.\n//  Copyright © 2019 杨科军. All rig"
  },
  {
    "path": "KJBannerViewDemo/Modules/View/KJCollectionViewCell.m",
    "chars": 814,
    "preview": "//\n//  KJCollectionViewCell.m\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2019/1/13.\n//  Copyright © 2019 杨科军. All rig"
  },
  {
    "path": "KJBannerViewDemo/Modules/ViewModel/KJViewModel.h",
    "chars": 594,
    "preview": "//\n//  KJViewModel.h\n//  KJBannerViewDemo\n//\n//  Created by 77。 on 2020/9/18.\n//  Copyright © 2020 杨科军. All rights reser"
  },
  {
    "path": "KJBannerViewDemo/Modules/ViewModel/KJViewModel.m",
    "chars": 2947,
    "preview": "//\n//  KJViewModel.m\n//  KJBannerViewDemo\n//\n//  Created by 77。 on 2020/9/18.\n//  Copyright © 2020 杨科军. All rights reser"
  },
  {
    "path": "KJBannerViewDemo/Supporting Files/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "chars": 2652,
    "preview": "{\n  \"images\" : [\n    {\n      \"size\" : \"20x20\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"WechatIMG44iPhoneNotificati"
  },
  {
    "path": "KJBannerViewDemo/Supporting Files/Assets.xcassets/Contents.json",
    "chars": 63,
    "preview": "{\n  \"info\" : {\n    \"author\" : \"xcode\",\n    \"version\" : 1\n  }\n}\n"
  },
  {
    "path": "KJBannerViewDemo/Supporting Files/Assets.xcassets/IMG_4931.imageset/Contents.json",
    "chars": 305,
    "preview": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"IMG_4931.jpg\",\n      \"scale\" : \"1x\"\n    },\n    {"
  },
  {
    "path": "KJBannerViewDemo/Supporting Files/Assets.xcassets/IMG_4931.imageset/Contents.json~Add 2.0.3",
    "chars": 305,
    "preview": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"IMG_4931.jpg\",\n      \"scale\" : \"1x\"\n    },\n    {"
  },
  {
    "path": "KJBannerViewDemo/Supporting Files/Assets.xcassets/IMG_4931.imageset/Contents.json~HEAD",
    "chars": 305,
    "preview": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"IMG_4931.jpg\",\n      \"scale\" : \"1x\"\n    },\n    {"
  },
  {
    "path": "KJBannerViewDemo/Supporting Files/Assets.xcassets/IMG_Guitar_52.imageset/Contents.json",
    "chars": 301,
    "preview": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"jita.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n   "
  },
  {
    "path": "KJBannerViewDemo/Supporting Files/Assets.xcassets/ax.imageset/Contents.json",
    "chars": 350,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"0161da5541af81000001a64bc753a4.jpg@1280w_1l_2o_100sh.jpg\",\n      \"idiom\" : \"u"
  },
  {
    "path": "KJBannerViewDemo/Supporting Files/Assets.xcassets/z_ds.imageset/Contents.json",
    "chars": 302,
    "preview": "{\n  \"images\" : [\n    {\n      \"filename\" : \"z_ds.png\",\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n   "
  },
  {
    "path": "KJBannerViewDemo/Supporting Files/Base.lproj/LaunchScreen.storyboard",
    "chars": 4113,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3"
  },
  {
    "path": "KJBannerViewDemo/Supporting Files/Base.lproj/Main.storyboard",
    "chars": 14436,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3"
  },
  {
    "path": "KJBannerViewDemo/Supporting Files/Info.plist",
    "chars": 1675,
    "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": "KJBannerViewDemo/Supporting Files/main.m",
    "chars": 374,
    "preview": "//\n//  main.m\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2018/12/22.\n//  Copyright © 2018 杨科军. All rights reserved.\n/"
  },
  {
    "path": "KJBannerViewDemo.xcodeproj/project.pbxproj",
    "chars": 36907,
    "preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 50;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
  },
  {
    "path": "KJBannerViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "chars": 161,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"self:KJBannerViewDem"
  },
  {
    "path": "KJBannerViewDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "chars": 238,
    "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": "KJBannerViewDemo.xcodeproj/xcshareddata/xcschemes/KJBannerViewDemo.xcscheme",
    "chars": 3340,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1240\"\n   version = \"1.3\">\n   <BuildAction\n      "
  },
  {
    "path": "LICENSE",
    "chars": 1053,
    "preview": "Copyright (c) 2018 yangkejun\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this softw"
  },
  {
    "path": "README.md",
    "chars": 1882,
    "preview": "# KJBannerView\n\n<p align=\"left\">\n<img src=\"https://upload-images.jianshu.io/upload_images/1933747-82138031f05852ab.gif?i"
  },
  {
    "path": "Sources/KJBannerHeader.h",
    "chars": 597,
    "preview": "//\n//  KJBannerHeader.h\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2018/12/23.\n//  Copyright © 2018 杨科军. All rights r"
  },
  {
    "path": "Sources/KJBannerView/KJBannerView.h",
    "chars": 3683,
    "preview": "//\n//  KJBannerView.h\n//  KJBannerView\n//\n//  Created by 杨科军 on 2018/2/27.\n//  Copyright © 2018年 杨科军. All rights reserve"
  },
  {
    "path": "Sources/KJBannerView/KJBannerView.m",
    "chars": 14709,
    "preview": "//\n//  KJBannerView.m\n//  KJBannerView\n//\n//  Created by 杨科军 on 2018/2/27.\n//  Copyright © 2018年 杨科军. All rights reserve"
  },
  {
    "path": "Sources/KJBannerView/KJBannerViewCell.h",
    "chars": 1286,
    "preview": "//\n//  KJBannerViewCell.h\n//  KJBannerView\n//\n//  Created by 杨科军 on 2018/2/27.\n//  Copyright © 2018年 杨科军. All rights res"
  },
  {
    "path": "Sources/KJBannerView/KJBannerViewCell.m",
    "chars": 9874,
    "preview": "//\n//  KJBannerViewCell.m\n//  KJBannerView\n//\n//  Created by 杨科军 on 2018/2/27.\n//  Copyright © 2018年 杨科军. All rights res"
  },
  {
    "path": "Sources/KJBannerView/KJBannerViewFlowLayout.h",
    "chars": 326,
    "preview": "//\n//  KJBannerViewFlowLayout.h\n//  KJBannerView\n//\n//  Created by 杨科军 on 2018/2/28.\n//  Copyright © 2018年 杨科军. All righ"
  },
  {
    "path": "Sources/KJBannerView/KJBannerViewFlowLayout.m",
    "chars": 1788,
    "preview": "//\n//  KJBannerViewFlowLayout.m\n//  KJBannerView\n//\n//  Created by 杨科军 on 2018/2/28.\n//  Copyright © 2018年 杨科军. All righ"
  },
  {
    "path": "Sources/KJBannerView/KJBannerViewTimer.h",
    "chars": 913,
    "preview": "//\n//  KJBannerViewTimer.h\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2020/12/7.\n//  Copyright © 2020 杨科军. All rights"
  },
  {
    "path": "Sources/KJBannerView/KJBannerViewTimer.m",
    "chars": 2104,
    "preview": "//\n//  KJBannerViewTimer.m\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2020/12/7.\n//  Copyright © 2020 杨科军. All rights"
  },
  {
    "path": "Sources/PageControl/KJPageControl.h",
    "chars": 1480,
    "preview": "//\n//  KJPageControl.h\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2019/5/27.\n//  Copyright © 2019 杨科军. All rights res"
  },
  {
    "path": "Sources/PageControl/KJPageControl.m",
    "chars": 8376,
    "preview": "//\n//  KJPageControl.m\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2019/5/27.\n//  Copyright © 2019 杨科军. All rights res"
  },
  {
    "path": "Sources/WebImage/KJAutoPurgingCache.h",
    "chars": 1004,
    "preview": "//\n//  KJAutoPurgingImageCache.h\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2021/2/19.\n//  Copyright © 2021 杨科军. All "
  },
  {
    "path": "Sources/WebImage/KJAutoPurgingCache.m",
    "chars": 4194,
    "preview": "//\n//  KJAutoPurgingImageCache.m\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2021/2/19.\n//  Copyright © 2021 杨科军. All "
  },
  {
    "path": "Sources/WebImage/KJImageCache.h",
    "chars": 1381,
    "preview": "//\n//  KJImageCache.h\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2020/12/7.\n//  Copyright © 2020 杨科军. All rights rese"
  },
  {
    "path": "Sources/WebImage/KJImageCache.m",
    "chars": 8301,
    "preview": "//\n//  KJImageCache.m\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2020/12/7.\n//  Copyright © 2020 杨科军. All rights rese"
  },
  {
    "path": "Sources/WebImage/KJNetworkManager.h",
    "chars": 1426,
    "preview": "//\n//  KJNetworkManager.h\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2020/12/7.\n//  Copyright © 2020 杨科军. All rights "
  },
  {
    "path": "Sources/WebImage/KJNetworkManager.m",
    "chars": 6443,
    "preview": "//\n//  KJNetworkManager.m\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2020/12/7.\n//  Copyright © 2020 杨科军. All rights "
  },
  {
    "path": "Sources/WebImage/KJWebImageDownloader.h",
    "chars": 879,
    "preview": "//\n//  KJWebImageDownloader.h\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2020/12/7.\n//  Copyright © 2020 杨科军. All rig"
  },
  {
    "path": "Sources/WebImage/KJWebImageDownloader.m",
    "chars": 6119,
    "preview": "//\n//  KJWebImageDownloader.m\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2020/12/7.\n//  Copyright © 2020 杨科军. All rig"
  },
  {
    "path": "Sources/WebImage/KJWebImageHeader.h",
    "chars": 337,
    "preview": "//\n//  KJWebImageHeader.h\n//  KJBannerViewDemo\n//\n//  Created by 77。 on 2021/11/6.\n//  Copyright © 2021 杨科军. All rights "
  },
  {
    "path": "Sources/WebImage/UIView+KJWebImage.h",
    "chars": 2186,
    "preview": "//\n//  UIView+KJWebImage.h\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2021/1/28.\n//  Copyright © 2021 杨科军. All rights"
  },
  {
    "path": "Sources/WebImage/UIView+KJWebImage.m",
    "chars": 13926,
    "preview": "//\n//  UIView+KJWebImage.m\n//  KJBannerViewDemo\n//\n//  Created by 杨科军 on 2021/1/28.\n//  Copyright © 2021 杨科军. All rights"
  }
]

// ... and 2 more files (download for full content)

About this extraction

This page contains the full source code of the yangKJ/KJBannerViewDemo GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 82 files (283.4 KB), approximately 78.1k tokens, and a symbol index with 8 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!