小说绘上架版本

This commit is contained in:
xtfei2011
2021-02-07 11:24:08 +08:00
commit ee5c1c8b12
1762 changed files with 115892 additions and 0 deletions
@@ -0,0 +1,15 @@
//
// YJAbstractDotView.h
// YJBannerViewDemo
//
// Created by YJHou on 2015/5/24.
// Copyright © Address:https://github.com/stackhou . All rights reserved.
//
#import <UIKit/UIKit.h>
@interface YJAbstractDotView : UIView
- (void)changeActivityState:(BOOL)active;
@end
@@ -0,0 +1,26 @@
//
// YJAbstractDotView.m
// YJBannerViewDemo
//
// Created by YJHou on 2015/5/24.
// Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved.
//
#import "YJAbstractDotView.h"
@implementation YJAbstractDotView
- (id)init{
@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:[NSString stringWithFormat:@"You must override %@ in %@", NSStringFromSelector(_cmd), self.class]
userInfo:nil];
}
- (void)changeActivityState:(BOOL)active{
@throw [NSException exceptionWithName:NSInternalInconsistencyException
reason:[NSString stringWithFormat:@"You must override %@ in %@", NSStringFromSelector(_cmd), self.class]
userInfo:nil];
}
@end
@@ -0,0 +1,17 @@
//
// YJAnimatedDotView.h
// YJBannerViewDemo
//
// Created by YJHou on 2015/5/24.
// Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved.
//
#import "YJAbstractDotView.h"
@interface YJAnimatedDotView : YJAbstractDotView
@property (nonatomic, strong) UIColor *dotColor;
@property (nonatomic, strong) UIColor *currentDotColor;
@property (nonatomic, assign) CGFloat resizeScale; /**< 调整比例 */
@end
@@ -0,0 +1,83 @@
//
// YJAnimatedDotView.m
// YJBannerViewDemo
//
// Created by YJHou on 2015/5/24.
// Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved.
//
#import "YJAnimatedDotView.h"
static CGFloat const kAnimateDuration = 0;
@implementation YJAnimatedDotView
- (instancetype)init{
self = [super init];
if (self) {
[self initialization];
}
return self;
}
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
[self initialization];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if (self) {
[self initialization];
}
return self;
}
- (void)setDotColor:(UIColor *)dotColor{
_dotColor = dotColor;
self.layer.borderColor = dotColor.CGColor;
}
- (void)setCurrentDotColor:(UIColor *)currentDotColor{
_currentDotColor = currentDotColor;
self.backgroundColor = [UIColor clearColor];
}
- (void)initialization{
_dotColor = [UIColor whiteColor];
_currentDotColor = [UIColor whiteColor];
self.backgroundColor = [UIColor clearColor];
self.layer.cornerRadius = CGRectGetWidth(self.frame) * 0.5;
self.layer.borderColor = [UIColor whiteColor].CGColor;
self.layer.borderWidth = 1.5;
self.resizeScale = 1.4f;
}
- (void)changeActivityState:(BOOL)active{
if (active) {
[self animateToActiveState];
} else {
[self animateToDeactiveState];
}
}
- (void)animateToActiveState{
[UIView animateWithDuration:kAnimateDuration delay:0 usingSpringWithDamping:.5 initialSpringVelocity:-20 options:UIViewAnimationOptionCurveLinear animations:^{
self.backgroundColor = self.currentDotColor;
self.layer.borderColor = [UIColor clearColor].CGColor;
self.transform = CGAffineTransformMakeScale(self.resizeScale, self.resizeScale);
} completion:nil];
}
- (void)animateToDeactiveState{
[UIView animateWithDuration:kAnimateDuration delay:0 usingSpringWithDamping:.5 initialSpringVelocity:0 options:UIViewAnimationOptionCurveLinear animations:^{
self.backgroundColor = [UIColor clearColor];
self.layer.borderColor = self.dotColor.CGColor;
self.transform = CGAffineTransformIdentity;
} completion:nil];
}
@end
@@ -0,0 +1,45 @@
//
// YJHollowPageControl.h
// YJBannerViewDemo
//
// Created by YJHou on 2015/5/24.
// Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved.
//
#import <UIKit/UIKit.h>
#import "YJAbstractDotView.h"
@class YJHollowPageControl;
@protocol YJHollowPageControlDelegate <NSObject>
@optional
- (void)yjHollowPageControl:(YJHollowPageControl *)pageControl didSelectPageAtIndex:(NSInteger)index;
@end
@interface YJHollowPageControl : UIControl
@property (nonatomic, assign) CGSize dotSize; /**< 圆点大小 默认8*8 */
@property (nonatomic, strong) UIImage *dotNormalImage; /**< 普通样式 */
@property (nonatomic, strong) UIImage *dotCurrentImage; /**< 选中样式 */
@property (nonatomic, strong) UIColor *dotNormalColor; /**< 点色 */
@property (nonatomic, strong) UIColor *dotCurrentColor; /**< 当前圆点的颜色 */
@property (nonatomic, strong) Class dotViewClass; /**< 圆点类 */
@property (nonatomic, weak) id<YJHollowPageControlDelegate> delegate; /**< 代理 */
@property (nonatomic, assign) CGFloat spacing; /**< 间距 默认 8 */
@property (nonatomic, assign) NSInteger numberOfPages; /**< 数量 */
@property (nonatomic, assign) NSInteger currentPage; /**< 当前位置 */
@property (nonatomic, assign) BOOL hidesForSinglePage; /**< 单个不显示 默认NO*/
@property (nonatomic, assign) BOOL shouldResizeFromCenter; /**< 是否调整大小 */
@property (nonatomic, assign) CGFloat resizeScale; /**< 调整比例 */
- (CGSize)sizeForNumberOfPages:(NSInteger)pageCount;
@end
@interface YJDotView : YJAbstractDotView
@end
@@ -0,0 +1,322 @@
//
// YJHollowPageControl.m
// YJBannerViewDemo
//
// Created by YJHou on 2015/5/24.
// Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved.
//
#import "YJHollowPageControl.h"
#import "YJAnimatedDotView.h"
static CGSize const kDefaultDotSize = {8, 8};
static NSInteger const kDefaultNumberOfPages = 0;
static NSInteger const kDefaultCurrentPage = 0;
static BOOL const kDefaultHideForSinglePage = NO;
static BOOL const kDefaultShouldResizeFromCenter = YES;
static NSInteger const kDefaultSpacingBetweenDots = 8;
@interface YJHollowPageControl ()
@property (nonatomic, strong) NSMutableArray *dots; /**< 保存所有的点 */
@end
@implementation YJHollowPageControl
- (id)init{
self = [super init];
if (self) {
[self _initializationSetting];
}
return self;
}
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
[self _initializationSetting];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if (self) {
[self _initializationSetting];
}
return self;
}
- (void)_initializationSetting{
self.dotViewClass = [YJAnimatedDotView class];
self.spacing = kDefaultSpacingBetweenDots;
self.numberOfPages = kDefaultNumberOfPages;
self.currentPage = kDefaultCurrentPage;
self.hidesForSinglePage = kDefaultHideForSinglePage;
self.shouldResizeFromCenter = kDefaultShouldResizeFromCenter;
}
#pragma mark - Touch event
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
UITouch *touch = [touches anyObject];
if (touch.view != self) {
NSInteger index = [self.dots indexOfObject:touch.view];
if ([self.delegate respondsToSelector:@selector(yjHollowPageControl:didSelectPageAtIndex:)]) {
[self.delegate yjHollowPageControl:self didSelectPageAtIndex:index];
}
}
}
- (void)sizeToFit{
[self updateFrame:YES];
}
- (CGSize)sizeForNumberOfPages:(NSInteger)pageCount{
return CGSizeMake((self.dotSize.width + self.spacing) * pageCount - self.spacing , self.dotSize.height);
}
- (void)updateDots{
if (self.numberOfPages == 0) {return;}
for (NSInteger i = 0; i < self.numberOfPages; i++) {
UIView *dot;
if (i < self.dots.count) {
dot = [self.dots objectOrNilAtIndex:i];
} else {
dot = [self generateDotView];
}
[self updateDotFrame:dot atIndex:i];
}
[self changeActivity:YES atIndex:self.currentPage];
[self hideForSinglePage];
}
/**
Update frame to fit current number of pages.
@param newFrame override Existing Frame
*/
- (void)updateFrame:(BOOL)newFrame{
CGPoint center = self.center;
CGSize requiredSize = [self sizeForNumberOfPages:self.numberOfPages];
// We apply requiredSize only if authorize to and necessary
if (newFrame || ((CGRectGetWidth(self.frame) < requiredSize.width || CGRectGetHeight(self.frame) < requiredSize.height) && !newFrame)) {
self.frame = CGRectMake(CGRectGetMinX(self.frame), CGRectGetMinY(self.frame), requiredSize.width, requiredSize.height);
if (self.shouldResizeFromCenter) {
self.center = center;
}
}
[self resetDotViews];
}
/**
* Update the frame of a specific dot at a specific index
*
* @param dot Dot view
* @param index Page index of dot
*/
- (void)updateDotFrame:(UIView *)dot atIndex:(NSInteger)index{
// Dots are always centered within view
CGFloat x = (self.dotSize.width + self.spacing) * index + ( (CGRectGetWidth(self.frame) - [self sizeForNumberOfPages:self.numberOfPages].width) / 2);
CGFloat y = (CGRectGetHeight(self.frame) - self.dotSize.height) / 2;
dot.frame = CGRectMake(x, y, self.dotSize.width, self.dotSize.height);
}
- (void)setDotCurrentColor:(UIColor *)currentDotColor{
_dotCurrentColor = currentDotColor;
}
- (void)setDotNormalColor:(UIColor *)dotColor{
_dotNormalColor = dotColor;
}
#pragma mark - Utils
/**
* Generate a dot view and add it to the collection
*
* @return The UIView object representing a dot
*/
- (UIView *)generateDotView{
UIView *dotView;
if (self.dotViewClass) {
dotView = [[self.dotViewClass alloc] initWithFrame:CGRectMake(0, 0, self.dotSize.width, self.dotSize.height)];
if ([dotView isKindOfClass:[YJAnimatedDotView class]]) {
if (self.resizeScale > 0) {
((YJAnimatedDotView *)dotView).resizeScale = self.resizeScale;
}
if (self.dotNormalColor) {
((YJAnimatedDotView *)dotView).dotColor = self.dotNormalColor;
}
if (self.dotCurrentColor){
((YJAnimatedDotView *)dotView).currentDotColor = self.dotCurrentColor;
}
}
} else {
dotView = [[UIImageView alloc] initWithImage:self.dotNormalImage];
dotView.contentMode = UIViewContentModeScaleAspectFit;
dotView.frame = CGRectMake(0, 0, self.dotSize.width, self.dotSize.height);
}
if (dotView) {
[self addSubview:dotView];
[self.dots addObject:dotView];
}
dotView.userInteractionEnabled = YES;
return dotView;
}
/**
* Change activity state of a dot view. Current/not currrent.
*
* @param active Active state to apply
* @param index Index of dot for state update
*/
- (void)changeActivity:(BOOL)active atIndex:(NSInteger)index{
if (self.dotViewClass) {
YJAbstractDotView *abstractDotView = (YJAbstractDotView *)[self.dots objectOrNilAtIndex:index];
if ([abstractDotView respondsToSelector:@selector(changeActivityState:)]) {
[abstractDotView changeActivityState:active];
} else {
}
} else if (self.dotNormalImage && self.dotCurrentImage) {
UIImageView *dotView = (UIImageView *)[self.dots objectOrNilAtIndex:index];
dotView.image = (active) ? self.dotCurrentImage : self.dotNormalImage;
}
}
- (void)resetDotViews{
for (UIView *dotView in self.dots) {
[dotView removeFromSuperview];
}
[self.dots removeAllObjects];
[self updateDots];
}
- (void)hideForSinglePage{
if (self.dots.count == 1 && self.hidesForSinglePage) {
self.hidden = YES;
} else {
self.hidden = NO;
}
}
#pragma mark - Setters
- (void)setNumberOfPages:(NSInteger)numberOfPages{
_numberOfPages = numberOfPages;
// Update dot position to fit new number of pages
[self resetDotViews];
}
- (void)setSpacing:(CGFloat)spacing{
_spacing = spacing;
[self resetDotViews];
}
- (void)setCurrentPage:(NSInteger)currentPage{
// If no pages, no current page to treat.
if (self.numberOfPages == 0 || currentPage == _currentPage) {
_currentPage = currentPage;
return;
}
// Pre set
[self changeActivity:NO atIndex:_currentPage];
_currentPage = currentPage;
// Post set
[self changeActivity:YES atIndex:_currentPage];
}
- (void)setDotNormalImage:(UIImage *)dotImage{
_dotNormalImage = dotImage;
[self resetDotViews];
self.dotViewClass = nil;
}
- (void)setDotCurrentImage:(UIImage *)currentDotimage{
_dotCurrentImage = currentDotimage;
[self resetDotViews];
self.dotViewClass = nil;
}
- (void)setDotViewClass:(Class)dotViewClass{
_dotViewClass = dotViewClass;
self.dotSize = CGSizeZero;
[self resetDotViews];
}
#pragma mark - Getter
- (CGSize)dotSize{
if (self.dotNormalImage && CGSizeEqualToSize(_dotSize, CGSizeZero)) {
_dotSize = self.dotNormalImage.size;
} else if (self.dotViewClass && CGSizeEqualToSize(_dotSize, CGSizeZero)) {
_dotSize = kDefaultDotSize;
return _dotSize;
}
return _dotSize;
}
#pragma mark - Lazy
- (NSMutableArray *)dots{
if (!_dots) {
_dots = [NSMutableArray array];
}
return _dots;
}
@end
@implementation YJDotView
- (instancetype)init{
self = [super init];
if (self) {
[self _initializationSetting];
}
return self;
}
- (id)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
[self _initializationSetting];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder{
self = [super initWithCoder:aDecoder];
if (self) {
[self _initializationSetting];
}
return self;
}
- (void)_initializationSetting{
self.backgroundColor = [UIColor clearColor];
self.layer.cornerRadius = CGRectGetWidth(self.frame) * 0.5;
self.layer.borderColor = [UIColor whiteColor].CGColor;
self.layer.borderWidth = 2;
}
- (void)changeActivityState:(BOOL)active{
if (active) {
self.backgroundColor = [UIColor whiteColor];
} else {
self.backgroundColor = [UIColor clearColor];
}
}
@end
Binary file not shown.

After

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 190 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 191 B

@@ -0,0 +1,19 @@
//
// UIView+YJBannerViewExt.h
// YJBannerViewDemo
//
// Created by YJHou on 2015/5/24.
// Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIView (YJBannerViewExt)
@property (nonatomic, assign) CGFloat x_bannerView;
@property (nonatomic, assign) CGFloat y_bannerView;
@property (nonatomic, assign) CGFloat width_bannerView;
@property (nonatomic, assign) CGFloat height_bannerView;
@end
@@ -0,0 +1,53 @@
//
// UIView+YJBannerViewExt.m
// YJBannerViewDemo
//
// Created by YJHou on 2015/5/24.
// Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved.
//
#import "UIView+YJBannerViewExt.h"
@implementation UIView (YJBannerViewExt)
- (void)setX_bannerView:(CGFloat)x_bannerView{
CGRect temp = self.frame;
temp.origin.x = x_bannerView;
self.frame = temp;
}
- (CGFloat)x_bannerView{
return self.frame.origin.x;
}
- (void)setY_bannerView:(CGFloat)y_bannerView{
CGRect temp = self.frame;
temp.origin.y = y_bannerView;
self.frame = temp;
}
- (CGFloat)y_bannerView{
return self.frame.origin.y;
}
- (void)setWidth_bannerView:(CGFloat)width_bannerView{
CGRect temp = self.frame;
temp.size.width = width_bannerView;
self.frame = temp;
}
- (CGFloat)width_bannerView{
return self.frame.size.width;
}
- (void)setHeight_bannerView:(CGFloat)height_bannerView{
CGRect temp = self.frame;
temp.size.height = height_bannerView;
self.frame = temp;
}
- (CGFloat)height_bannerView{
return self.frame.size.height;
}
@end
@@ -0,0 +1,24 @@
//
// YJBannerViewCell.h
// YJBannerViewDemo
//
// Created by YJHou on 2015/5/24.
// Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved.
//
#import <UIKit/UIKit.h>
@interface YJBannerViewCell : UICollectionViewCell
@property (nonatomic, strong) UIColor *titleLabelTextColor;
@property (nonatomic, strong) UIFont *titleLabelTextFont;
@property (nonatomic, strong) UIColor *titleLabelBackgroundColor;
@property (nonatomic, assign) CGFloat titleLabelHeight;
@property (nonatomic, assign) CGFloat titleLabelEdgeMargin;
@property (nonatomic, assign) NSTextAlignment titleLabelTextAlignment;
@property (nonatomic, assign) UIViewContentMode showImageViewContentMode; /**< 填充样式 默认UIViewContentModeScaleToFill */
@property (nonatomic, assign) BOOL isConfigured;
- (void)cellWithSelectorString:(NSString *)selectorString imagePath:(NSString *)imagePath placeholderImage:(UIImage *)placeholderImage title:(NSString *)title;
@end
@@ -0,0 +1,149 @@
//
// YJBannerViewCell.m
// YJBannerViewDemo
//
// Created by YJHou on 2015/5/24.
// Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved.
//
#import "YJBannerViewCell.h"
#import "UIView+YJBannerViewExt.h"
@interface YJBannerViewCell ()
@property (nonatomic, strong) UIImageView *showImageView; /**< 显示图片 */
@property (nonatomic, strong) UILabel *titleLabel; /**< 标题头 */
@property (nonatomic, strong) UIView *titleLabelBgView; /**< 标题背景 */
@end
@implementation YJBannerViewCell
- (instancetype)initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]) {
[self _setUpMainView];
}
return self;
}
- (void)_setUpMainView{
[self.contentView addSubview:self.showImageView];
[self.contentView addSubview:self.titleLabelBgView];
[self.contentView addSubview:self.titleLabel];
}
#pragma mark - Setter && Getter
- (void)setTitleLabelBackgroundColor:(UIColor *)titleLabelBackgroundColor{
_titleLabelBackgroundColor = titleLabelBackgroundColor;
self.titleLabelBgView.backgroundColor = titleLabelBackgroundColor;
}
- (void)setTitleLabelTextColor:(UIColor *)titleLabelTextColor{
_titleLabelTextColor = titleLabelTextColor;
self.titleLabel.textColor = titleLabelTextColor;
}
- (void)setTitleLabelTextFont:(UIFont *)titleLabelTextFont{
_titleLabelTextFont = titleLabelTextFont;
self.titleLabel.font = titleLabelTextFont;
}
-(void)setTitleLabelTextAlignment:(NSTextAlignment)titleLabelTextAlignment{
_titleLabelTextAlignment = titleLabelTextAlignment;
self.titleLabel.textAlignment = titleLabelTextAlignment;
}
- (void)setShowImageViewContentMode:(UIViewContentMode)showImageViewContentMode{
_showImageViewContentMode = showImageViewContentMode;
self.showImageView.contentMode = showImageViewContentMode;
}
- (void)layoutSubviews{
[super layoutSubviews];
CGFloat titleBgViewlH = self.titleLabelHeight;
self.showImageView.frame = self.bounds;
CGFloat titlBgViewX = 0.0f;
CGFloat titleBgViewY = self.height_bannerView - titleBgViewlH;
CGFloat titleBgViewW = self.width_bannerView - 2 * titlBgViewX;
_titleLabelBgView.frame = CGRectMake(titlBgViewX, titleBgViewY, titleBgViewW, titleBgViewlH);
CGFloat titleLabelH = titleBgViewlH;
CGFloat titleLabelX = self.titleLabelEdgeMargin;
CGFloat titleLabelY = titleBgViewY;
CGFloat titleLabelW = self.width_bannerView - 2 * titleLabelX;
_titleLabel.frame = CGRectMake(titleLabelX, titleLabelY, titleLabelW, titleLabelH);
}
#pragma mark - 刷新数据
- (void)cellWithSelectorString:(NSString *)selectorString imagePath:(NSString *)imagePath placeholderImage:(UIImage *)placeholderImage title:(NSString *)title{
if (imagePath) {
self.showImageView.hidden = NO;
if ([imagePath isKindOfClass:[NSString class]]) {
if ([imagePath hasPrefix:@"http"]) {
// 检验方法是否可用
SEL selector = NSSelectorFromString(selectorString);
if ([self.showImageView respondsToSelector:selector]) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
[self.showImageView performSelector:selector withObject:[NSURL URLWithString:imagePath] withObject:placeholderImage];
#pragma clang diagnostic pop
}
} else {
if (imagePath.length > 0) {
UIImage *image = [UIImage imageNamed:imagePath];
if (!image) {
image = [UIImage imageWithContentsOfFile:imagePath];
}
self.showImageView.image = image;
}
}
} else if ([imagePath isKindOfClass:[UIImage class]]) {
self.showImageView.image = (UIImage *)imagePath;
}else{
self.showImageView.image = placeholderImage;
}
}else{
self.showImageView.hidden = YES;
}
if (title.length > 0) {
self.titleLabel.text = title;
self.titleLabel.hidden = NO;
self.titleLabelBgView.hidden = NO;
}else{
self.titleLabel.hidden = YES;
self.titleLabelBgView.hidden = YES;
}
}
#pragma mark - Lazy
- (UIImageView *)showImageView{
if (!_showImageView) {
_showImageView = [[UIImageView alloc] init];
}
return _showImageView;
}
- (UILabel *)titleLabel{
if (!_titleLabel) {
_titleLabel = [[UILabel alloc] init];
_titleLabel.hidden = YES;
_titleLabel.backgroundColor = [UIColor clearColor];
}
return _titleLabel;
}
- (UIView *)titleLabelBgView{
if (!_titleLabelBgView) {
_titleLabelBgView = [[UIView alloc] init];
_titleLabelBgView.hidden = YES;
}
return _titleLabelBgView;
}
@end
@@ -0,0 +1,13 @@
//
// YJBannerViewCollectionView.h
// YJBannerViewDemo
//
// Created by YJHou on 2017/11/21.
// Copyright © 2017年 Address:https://github.com/stackhou . All rights reserved.
//
#import <UIKit/UIKit.h>
@interface YJBannerViewCollectionView : UICollectionView <UIGestureRecognizerDelegate>
@end
@@ -0,0 +1,13 @@
//
// YJBannerViewCollectionView.m
// YJBannerViewDemo
//
// Created by YJHou on 2017/11/21.
// Copyright © 2017年 Address:https://github.com/stackhou . All rights reserved.
//
#import "YJBannerViewCollectionView.h"
@implementation YJBannerViewCollectionView
@end
@@ -0,0 +1,26 @@
//
// YJBannerViewFooter.h
// YJBannerViewDemo
//
// Created by YJHou on 2015/5/24.
// Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved.
//
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSInteger, YJBannerViewStatus) {
YJBannerViewStatusIdle = 0, // 闲置
YJBannerViewStatusTrigger // 触发
};
@interface YJBannerViewFooter : UICollectionReusableView
@property (nonatomic, assign) YJBannerViewStatus state;
@property (nonatomic, strong) UIFont *footerTitleFont;
@property (nonatomic, strong) UIColor *footerTitleColor;
@property (nonatomic, copy) NSString *IndicateImageName; /**< 指示图片的名字 */
@property (nonatomic, copy) NSString *idleTitle; /**< 闲置 */
@property (nonatomic, copy) NSString *triggerTitle; /**< 触发 */
@end
@@ -0,0 +1,125 @@
//
// YJBannerViewFooter.m
// YJBannerViewDemo
//
// Created by YJHou on 2015/5/24.
// Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved.
//
#import "YJBannerViewFooter.h"
#define YJ_ARROW_SIZE 15.0f
@interface YJBannerViewFooter ()
@property (nonatomic, strong) UIImageView *arrowView;
@property (nonatomic, strong) UILabel *label;
@end
@implementation YJBannerViewFooter
@synthesize idleTitle = _idleTitle;
@synthesize triggerTitle = _triggerTitle;
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
[self addSubview:self.arrowView];
[self addSubview:self.label];
self.state = YJBannerViewStatusIdle;
}
return self;
}
- (void)layoutSubviews{
[super layoutSubviews];
CGFloat arrowX = self.bounds.size.width * 0.5 - YJ_ARROW_SIZE - 2.5;
CGFloat arrowY = (self.bounds.size.height - YJ_ARROW_SIZE) * 0.5;
CGFloat arrowW = YJ_ARROW_SIZE;
CGFloat arrowH = YJ_ARROW_SIZE;
self.arrowView.frame = CGRectMake(arrowX, arrowY, arrowW, arrowH);
CGFloat labelX = self.bounds.size.width * 0.5 + 2.5;
CGFloat labelY = 0;
CGFloat labelW = YJ_ARROW_SIZE;
CGFloat labelH = self.bounds.size.height;
self.label.frame = CGRectMake(labelX, labelY, labelW, labelH);
}
#pragma mark - setters & getters
- (void)setState:(YJBannerViewStatus)state{
_state = state;
switch (state) {
case YJBannerViewStatusIdle:{
self.label.text = self.idleTitle;
[UIView animateWithDuration:0.25 animations:^{
self.arrowView.transform = CGAffineTransformMakeRotation(0);
}];
}
break;
case YJBannerViewStatusTrigger:{
self.label.text = self.triggerTitle;
[UIView animateWithDuration:0.25 animations:^{
self.arrowView.transform = CGAffineTransformMakeRotation(M_PI);
}];
}
break;
default:
break;
}
}
#pragma mark - Setter
- (void)setFooterTitleFont:(UIFont *)footerTitleFont{
_footerTitleFont = footerTitleFont;
self.label.font = _footerTitleFont;
}
- (void)setFooterTitleColor:(UIColor *)footerTitleColor{
_footerTitleColor = footerTitleColor;
self.label.textColor = _footerTitleColor;
}
- (void)setIndicateImageName:(NSString *)IndicateImageName{
_IndicateImageName = IndicateImageName;
if (_IndicateImageName.length > 0 && self.arrowView.image == nil) {
self.arrowView.image = [UIImage imageNamed:_IndicateImageName];
}
}
#pragma mark - Lazy
- (UIImageView *)arrowView{
if (!_arrowView) {
_arrowView = [[UIImageView alloc] init];
}
return _arrowView;
}
- (UILabel *)label{
if (!_label) {
_label = [[UILabel alloc] init];
_label.numberOfLines = 0;
}
return _label;
}
- (void)setIdleTitle:(NSString *)idleTitle{
_idleTitle = idleTitle;
if (self.state == YJBannerViewStatusIdle) {
self.label.text = idleTitle;
}
}
- (void)setTriggerTitle:(NSString *)triggerTitle{
_triggerTitle = triggerTitle;
if (self.state == YJBannerViewStatusTrigger) {
self.label.text = triggerTitle;
}
}
@end
@@ -0,0 +1,19 @@
//
// YJMallCollectionViewCell.h
// WXReader
//
// Created by Andrew on 2019/5/28.
// Copyright © 2019 Andrew. All rights reserved.
//
#import <UIKit/UIKit.h>
NS_ASSUME_NONNULL_BEGIN
@interface YJMallCollectionViewCell : UICollectionViewCell
@property (nonatomic, strong) TFBannerModel *bannerModel;
@end
NS_ASSUME_NONNULL_END
@@ -0,0 +1,85 @@
//
// YJMallCollectionViewCell.m
// WXReader
//
// Created by Andrew on 2019/5/28.
// Copyright © 2019 Andrew. All rights reserved.
//
#import "YJMallCollectionViewCell.h"
#import "UIView+AZGradient.h"
@implementation YJMallCollectionViewCell
{
UIImageView *backHoldImageView;
UIView *backFrostedGlassView;
YYAnimatedImageView *bannerImageView;
}
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self createSubViews];
}
return self;
}
- (void)createSubViews
{
backHoldImageView = [[UIImageView alloc] init];
backHoldImageView.clipsToBounds = YES;
backHoldImageView.contentMode = UIViewContentModeScaleAspectFill;
[self addSubview:backHoldImageView];
[backHoldImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self);
}];
backFrostedGlassView = [[UIView alloc] init];
[self addSubview:backFrostedGlassView];
[backFrostedGlassView mas_makeConstraints:^(MASConstraintMaker *make) {
make.edges.mas_equalTo(self);
}];
bannerImageView = [[YYAnimatedImageView alloc] init];
bannerImageView.layer.cornerRadius = 4;
bannerImageView.clipsToBounds = YES;
bannerImageView.contentMode = UIViewContentModeScaleAspectFill;
[self addSubview:bannerImageView];
[bannerImageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.mas_equalTo(kHalfMargin + kQuarterMargin);
make.bottom.mas_equalTo(self.mas_bottom);
make.width.mas_equalTo(SCREEN_WIDTH - 2 * (kHalfMargin + kQuarterMargin));
make.height.mas_equalTo(kGeometricHeight((SCREEN_WIDTH - 2 * (kHalfMargin + kQuarterMargin)), 5, 3));
}];
}
- (void)setBannerModel:(TFBannerModel *)bannerModel
{
_bannerModel = bannerModel;
if (!bannerModel) {
return;
}
@try {
[[YYWebImageManager sharedManager] requestImageWithURL:[NSURL URLWithString:bannerModel.image?:@""] options:YYWebImageOptionSetImageWithFadeAnimation progress:nil transform:nil completion:^(UIImage * _Nullable image, NSURL * _Nonnull url, YYWebImageFromType from, YYWebImageStage stage, NSError * _Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
self->backHoldImageView.image = image;
[self->backFrostedGlassView az_setGradientBackgroundWithColors:@[[UIColor whiteColor], [[UIColor colorWithHexString:bannerModel.color?:@"#000000"] colorWithAlphaComponent:0.8]] locations:nil startPoint:CGPointMake(1.0, 1.0) endPoint:CGPointMake(1.0, 0.0)];
});
}];
} @catch (NSException *exception) {
} @finally {
}
[bannerImageView setImageWithURL:[NSURL URLWithString:bannerModel.image?:@""] placeholder:HoldImage options:YYWebImageOptionSetImageWithFadeAnimation completion:nil];
}
@end
@@ -0,0 +1,214 @@
//
// YJBannerView.h
// YJBannerViewDemo
//
// Created by YJHou on 2015/5/24.
// Copyright © 2015年 Address:https://github.com/stackhou . All rights reserved.
//
/**
__ __ _ ____ __ ___
\ \ / / | | __ ) __ _ _ __ _ __ ___ _ __ \ / (_) _____ __
\ V / | | _ \ / _` | '_ \| '_ \ / _ \ '__\ \ / /| |/ _ \ \ /\ / /
| | |_| | |_) | (_| | | | | | | | __/ | \ V / | | __/\ V V /
|_|\___/|____/ \__,_|_| |_|_| |_|\___|_| \_/ |_|\___| \_/\_/
********* Current-Version : 2.3.8 ************
Version record: https://github.com/stackhou/YJBannerViewOC
*/
#import <UIKit/UIKit.h>
#import "YJBannerViewCollectionView.h"
/** 指示器位置 */
typedef NS_ENUM(NSInteger, PageControlAliment) {
PageControlAlimentLeft = 0, // 居左
PageControlAlimentCenter, // 居中
PageControlAlimentRight // 居右
};
/** 指示器样式 */
typedef NS_ENUM(NSInteger, PageControlStyle) {
PageControlNone = 0, // 无
PageControlSystem, // 系统自带
PageControlHollow, // 空心的
PageControlCustom // 自定义 需要图片Dot
};
/** 滚动方向 */
typedef NS_ENUM(NSInteger, BannerViewDirection) {
BannerViewDirectionLeft = 0, // 水平向左
BannerViewDirectionRight, // 水平向右
BannerViewDirectionTop, // 竖直向上
BannerViewDirectionBottom // 竖直向下
};
@class YJBannerView;
@protocol YJBannerViewDataSource, YJBannerViewDelegate;
@interface YJBannerView : UIView
@property (nonatomic, strong) UIImageView *backgroundImageView; /**< 数据为空时的背景图 */
@property (nonatomic, strong, readonly) UICollectionViewFlowLayout *flowLayout;
@property (nonatomic, strong, readonly) YJBannerViewCollectionView *collectionView;
@property (nonatomic, weak) id<YJBannerViewDataSource> dataSource; /**< 数据源代理 */
@property (nonatomic, weak) id<YJBannerViewDelegate> delegate; /**< 代理 */
@property (nonatomic, assign) IBInspectable BOOL autoScroll; /**< 是否自动 默认YES */
@property (nonatomic, assign) IBInspectable CGFloat autoDuration; /**< 自动滚动时间间隔 默认3s */
@property (nonatomic, assign) IBInspectable BOOL cycleScrollEnable; /**< 是否首尾循环 默认是YES */
@property (nonatomic, assign) BannerViewDirection bannerViewScrollDirection; /**< 滚动方向 默认水平向左 */
@property (nonatomic, assign) BOOL bannerGestureEnable; /**< 手势是否可用 默认可用YES */
@property (nonatomic, assign) IBInspectable BOOL showFooter; /**< 显示footerView 默认是 NO 设置为YES 后将 autoScroll和cycleScrollEnable 自动置为NO 只支持水平向左 */
@property (nonatomic, assign) NSInteger repeatCount; /**< 数据源重复次数 默认是200 若循环必须大于2的偶数 */
@property (nonatomic, strong) UIImage *placeholderImage; /**< 默认图片 */
@property (nonatomic, strong) UIImage *emptyImage; /**< 空数据图片 */
@property (nonatomic, copy) NSString *bannerViewSelectorString; /**< 自定义设置网络和默认图片的方法 */
@property (nonatomic, assign) UIViewContentMode bannerImageViewContentMode; /**< 填充样式 默认UIViewContentModeScaleAspectFill */
@property (nonatomic, assign) PageControlAliment pageControlAliment; /**< 指示器的位置 默认是Center */
@property (nonatomic, assign) PageControlStyle pageControlStyle; /**< 指示器样式 默认System */
@property (nonatomic, assign) CGFloat pageControlBottomMargin; /**< 指示器距离底部的间距 默认10 */
@property (nonatomic, assign) CGFloat pageControlHorizontalEdgeMargin; /**< 指示器水平方向上的边缘间距 默认10 */
@property (nonatomic, assign) CGFloat pageControlPadding; /**< 指示器水平方向上间距 默认 5 系统样式无效 */
@property (nonatomic, assign) CGSize pageControlDotSize; /**< 指示器圆标大小 默认 8*8*/
@property (nonatomic, strong) UIColor *pageControlNormalColor; /**< 指示器正常颜色 */
@property (nonatomic, strong) UIColor *pageControlHighlightColor; /**< 指示器小圆标颜色 */
@property (nonatomic, strong) UIImage *customPageControlNormalImage; /**< 指示器小圆点正常的图片 */
@property (nonatomic, strong) UIImage *customPageControlHighlightImage; /**< 当前分页控件图片 */
@property (nonatomic, strong) UIFont *titleFont; /**< 文字大小 默认14.0f */
@property (nonatomic, strong) UIColor *titleTextColor; /**< 文字颜色 默认 whiteColor */
@property (nonatomic, assign) NSTextAlignment titleAlignment; /**< 文字对齐方式 默认 Left */
@property (nonatomic, strong) UIColor *titleBackgroundColor; /**< 文字背景颜色 默认 黑0.5 */
@property (nonatomic, assign) CGFloat titleHeight; /**< 文字高度 默认30 */
@property (nonatomic, assign) CGFloat titleEdgeMargin; /**< 文字边缘间距 默认是10 */
@property (nonatomic, copy) NSString *footerIndicateImageName; /**< footer 指示图片名字 默认是自带的 */
@property (nonatomic, copy) NSString *footerNormalTitle; /**< footer 常态Title 默认 "拖动查看详情" */
@property (nonatomic, copy) NSString *footerTriggerTitle; /**< footer Trigger Title 默认 "释放查看详情" */
@property (nonatomic, strong) UIFont *footerTitleFont; /**< footer Font 默认 12 */
@property (nonatomic, strong) UIColor *footerTitleColor; /**< footer TitleColoe 默认是 darkGrayColor */
@property (nonatomic, copy) void(^didScroll2IndexBlock)(NSInteger index);
@property (nonatomic, copy) void(^didSelectItemAtIndexBlock)(NSInteger index);
@property (nonatomic, copy) void(^didEndTriggerFooterBlock)(void);
/**
创建bannerView实例的方法
@param frame bannerView的Frame
@param dataSource 数据源代理
@param delegate 普通代理
@param emptyImage 空数据图片
@param placeholderImage 默认图片
@param selectorString 必须是 UIImageView 设置图片和placeholderImage的方法 如: @"sd_setImageWithURL:placeholderImage:", 分别接收NSURL和UIImage两个参数
@return YJBannerView 实例
*/
+ (YJBannerView *)bannerViewWithFrame:(CGRect)frame
dataSource:(id<YJBannerViewDataSource>)dataSource
delegate:(id<YJBannerViewDelegate>)delegate
emptyImage:(UIImage *)emptyImage
placeholderImage:(UIImage *)placeholderImage
selectorString:(NSString *)selectorString;
/** 刷新BannerView数据 */
- (void)reloadData;
/** 停止定时器接口 */
- (void)invalidateTimerWhenAutoScroll;
/** 重新开启定时器 */
- (void)startTimerWhenAutoScroll;
/** 调整滚动到指定位置 */
- (void)adjustBannerViewScrollToIndex:(NSInteger)index animated:(BOOL)animated;
/** 如果卡屏请在控制器 viewWillAppear 内调用此方法 */
- (void)adjustBannerViewWhenCardScreen;
@end
#pragma mark - 协议部分
@protocol YJBannerViewDataSource <NSObject>
@required
/**
显示Banner数据源代理方法
@param bannerView 当前Banner
@return 兼容 http(s):// 和 本地图片Name 类型: NSString 数组
*/
- (NSArray *)bannerViewImages:(YJBannerView *)bannerView;
@optional
/** 文字数据源 */
- (NSArray *)bannerViewTitles:(YJBannerView *)bannerView;
/**
自定义 View 要同时配合实现以下3个方法
@param bannerView 当前的Banner
@return 需要注册的自定义View类的集合. e.g.: @[[CustomViewA class], [CustomViewB class]]
*/
- (NSArray *)bannerViewRegistCustomCellClass:(YJBannerView *)bannerView;
/** 根据 Index 选择使用哪个 reuseIdentifier */
- (Class)bannerView:(YJBannerView *)bannerView reuseIdentifierForIndex:(NSInteger)index;
/** 自定义 View 刷新数据或者其他配置 */
- (UICollectionViewCell *)bannerView:(YJBannerView *)bannerView customCell:(UICollectionViewCell *)customCell index:(NSInteger)index;
/** Footer 高度 默认是 49.0 */
- (CGFloat)bannerViewFooterViewHeight:(YJBannerView *)bannerView;
@end
@protocol YJBannerViewDelegate <NSObject>
@optional
/** 正在滚动的位置及偏移量 */
- (void)bannerView:(YJBannerView *)bannerView didScrollCurrentIndex:(NSInteger)currentIndex contentOffset:(CGFloat)contentOffset;
/** 滚动到 index */
- (void)bannerView:(YJBannerView *)bannerView didScroll2Index:(NSInteger)index;
/** 点击回调 */
- (void)bannerView:(YJBannerView *)bannerView didSelectItemAtIndex:(NSInteger)index;
/** BannerView Footer 回调 */
- (void)bannerViewFooterDidEndTrigger:(YJBannerView *)bannerView;
@end
@@ -0,0 +1,905 @@
//
// YJBannerView.m
// YJBannerViewDemo
//
// Created by YJHou on 2015/5/24.
// Copyright © 2015年 Address:https://github.com/stackhou/YJBannerViewOC . All rights reserved.
//
/**
__ __ _ ____ __ ___
\ \ / / | | __ ) __ _ _ __ _ __ ___ _ __ \ / (_) _____ __
\ V / | | _ \ / _` | '_ \| '_ \ / _ \ '__\ \ / /| |/ _ \ \ /\ / /
| | |_| | |_) | (_| | | | | | | | __/ | \ V / | | __/\ V V /
|_|\___/|____/ \__,_|_| |_|_| |_|\___|_| \_/ |_|\___| \_/\_/
*/
#import "YJBannerView.h"
#import "YJBannerViewCell.h"
#import "UIView+YJBannerViewExt.h"
#import "YJHollowPageControl.h"
#import "YJBannerViewFooter.h"
static NSString *const bannerViewCellId = @"YJBannerView";
static NSString *const bannerViewFooterId = @"YJBannerViewFooter";
static NSInteger const totalCollectionViewCellCount = 200;
#define kPageControlDotDefaultSize CGSizeMake(8, 8)
#define BANNER_FOOTER_HEIGHT 49.0
@interface YJBannerView () <UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout> {
YJBannerViewCollectionView *_collectionView;
UICollectionViewFlowLayout *_flowLayout;
}
@property (nonatomic, weak) UIControl *pageControl;
@property (nonatomic, weak) NSTimer *timer;
@property (nonatomic, assign) NSInteger totalBannerItemsCount;
@property (nonatomic, strong) NSArray *saveScrollViewGestures;
@property (nonatomic, strong) YJBannerViewFooter *bannerFooter;
@property (nonatomic, strong) NSArray *showNewDatasource;
@property (nonatomic, assign) CGFloat lastContentOffset;
@end
@implementation YJBannerView
@synthesize autoScroll = _autoScroll;
@synthesize cycleScrollEnable = _cycleScrollEnable;
@synthesize bannerImageViewContentMode = _bannerImageViewContentMode;
@synthesize pageControlNormalColor = _pageControlNormalColor;
@synthesize pageControlHighlightColor = _pageControlHighlightColor;
#pragma mark - Public API
+ (YJBannerView *)bannerViewWithFrame:(CGRect)frame
dataSource:(id<YJBannerViewDataSource>)dataSource
delegate:(id<YJBannerViewDelegate>)delegate
emptyImage:(UIImage *)emptyImage
placeholderImage:(UIImage *)placeholderImage
selectorString:(NSString *)selectorString{
YJBannerView *bannerView = [[YJBannerView alloc] initWithFrame:frame];
bannerView.dataSource = dataSource;
bannerView.delegate = delegate;
bannerView.bannerViewSelectorString = selectorString;
bannerView.emptyImage = emptyImage;
bannerView.placeholderImage = placeholderImage;
return bannerView;
}
- (void)reloadData{
[self invalidateTimer];
self.showNewDatasource = [self _getImageDataSources];
// Hidden when data source is greater than zero
self.backgroundImageView.hidden = ([self _imageDataSources].count > 0);
if ([self _imageDataSources].count > 1) {
self.collectionView.scrollEnabled = YES;
[self setAutoScroll:self.autoScroll];
} else {
if ([self _imageDataSources].count == 0) { self.showFooter = NO; }
BOOL isCan = ([self _imageDataSources].count == 0)?NO:(self.showFooter?YES:NO);
self.collectionView.scrollEnabled = isCan;
[self invalidateTimerWhenAutoScroll];
}
[self _setFooterViewCanShow:self.showFooter];
[self _setupPageControl];
// Regist Custom Cell
if (self.dataSource && [self.dataSource respondsToSelector:@selector(bannerViewRegistCustomCellClass:)] && [self.dataSource bannerViewRegistCustomCellClass:self]) {
NSArray *clazzs = [self.dataSource bannerViewRegistCustomCellClass:self];
for (Class clazz in clazzs) {
[self.collectionView registerClass:clazz forCellWithReuseIdentifier:NSStringFromClass(clazz)];
}
}
[self.collectionView reloadData];
}
- (instancetype)initWithFrame:(CGRect)frame{
self = [super initWithFrame:frame];
if (self) {
[self _initSetting];
[self addSubview:self.collectionView];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder{
if (self = [super initWithCoder:aDecoder]) {
[self _initSetting];
[self addSubview:self.collectionView];
}
return self;
}
- (void)awakeFromNib{
[super awakeFromNib];
[self _initSetting];
[self addSubview:self.collectionView];
}
/** Initialize the default settings */
- (void)_initSetting{
self.backgroundColor = [UIColor whiteColor];
_autoDuration = 3.0;
_autoScroll = YES;
_pageControlStyle = PageControlSystem;
_pageControlAliment = PageControlAlimentCenter;
_pageControlDotSize = kPageControlDotDefaultSize;
_pageControlBottomMargin = 10.0f;
_pageControlHorizontalEdgeMargin = 10.0f;
_pageControlPadding = 5.0f;
_titleHeight = 30.0f;
_titleEdgeMargin = 10.0f;
_titleAlignment = NSTextAlignmentLeft;
_bannerGestureEnable = YES;
_cycleScrollEnable = YES;
_showFooter = NO;
_footerIndicateImageName = @"YJBannerView.bundle/yjbanner_arrow.png";
_footerNormalTitle = TFLocalizedString(@"拖动查看详情");
_footerTriggerTitle = TFLocalizedString(@"释放查看详情");
}
#pragma mark - Setter && Getter
- (void)setEmptyImage:(UIImage *)emptyImage{
_emptyImage = emptyImage;
if (emptyImage) {
self.backgroundImageView.image = emptyImage;
}
}
- (void)setPageControlDotSize:(CGSize)pageControlDotSize{
_pageControlDotSize = pageControlDotSize;
[self _setupPageControl];
if ([self.pageControl isKindOfClass:[YJHollowPageControl class]]) {
YJHollowPageControl *pageContol = (YJHollowPageControl *)_pageControl;
pageContol.dotSize = pageControlDotSize;
}
}
- (void)setPageControlStyle:(PageControlStyle)pageControlStyle{
_pageControlStyle = pageControlStyle;
[self _setupPageControl];
}
- (void)setPageControlNormalColor:(UIColor *)pageControlNormalColor{
_pageControlNormalColor = pageControlNormalColor;
if ([self.pageControl isKindOfClass:[YJHollowPageControl class]]) {
YJHollowPageControl *pageControl = (YJHollowPageControl *)_pageControl;
pageControl.dotNormalColor = pageControlNormalColor;
}else if ([self.pageControl isKindOfClass:[UIPageControl class]]) {
UIPageControl *pageControl = (UIPageControl *)_pageControl;
pageControl.pageIndicatorTintColor = pageControlNormalColor;
}
}
- (void)setPageControlHighlightColor:(UIColor *)pageControlHighlightColor{
_pageControlHighlightColor = pageControlHighlightColor;
if ([self.pageControl isKindOfClass:[YJHollowPageControl class]]) {
YJHollowPageControl *pageControl = (YJHollowPageControl *)_pageControl;
pageControl.dotCurrentColor = pageControlHighlightColor;
} else if ([self.pageControl isKindOfClass:[UIPageControl class]]){
UIPageControl *pageControl = (UIPageControl *)_pageControl;
pageControl.currentPageIndicatorTintColor = pageControlHighlightColor;
}
}
- (void)setCustomPageControlNormalImage:(UIImage *)customPageControlNormalImage{
_customPageControlNormalImage = customPageControlNormalImage;
[self setCustomPageControlDotImage:customPageControlNormalImage isCurrentPageDot:NO];
}
- (void)setCustomPageControlHighlightImage:(UIImage *)customPageControlHighlightImage{
_customPageControlHighlightImage = customPageControlHighlightImage;
[self setCustomPageControlDotImage:customPageControlHighlightImage isCurrentPageDot:YES];
}
- (void)setCustomPageControlDotImage:(UIImage *)image isCurrentPageDot:(BOOL)isCurrentPageDot{
if (!image || !self.pageControl) return;
if ([self.pageControl isKindOfClass:[YJHollowPageControl class]]) {
YJHollowPageControl *pageControl = (YJHollowPageControl *)_pageControl;
if (isCurrentPageDot) {
pageControl.dotCurrentImage = image;
} else {
pageControl.dotNormalImage = image;
}
}
}
- (void)setAutoScroll:(BOOL)autoScroll{
_autoScroll = autoScroll;
[self invalidateTimer];
if (autoScroll) {
[self _setupTimer];
}
}
- (void)setBannerViewScrollDirection:(BannerViewDirection)bannerViewScrollDirection{
if (self.showFooter && bannerViewScrollDirection != BannerViewDirectionLeft) {
bannerViewScrollDirection = BannerViewDirectionLeft;
}
_bannerViewScrollDirection = bannerViewScrollDirection;
if (bannerViewScrollDirection == BannerViewDirectionLeft || bannerViewScrollDirection == BannerViewDirectionRight) {
self.flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
}else if (bannerViewScrollDirection == BannerViewDirectionTop || bannerViewScrollDirection == BannerViewDirectionBottom){
self.flowLayout.scrollDirection = UICollectionViewScrollDirectionVertical;
}
}
- (void)setAutoDuration:(CGFloat)autoDuration{
_autoDuration = autoDuration;
[self setAutoScroll:self.autoScroll];
}
- (void)setBannerGestureEnable:(BOOL)bannerGestureEnable{
if (_bannerGestureEnable && bannerGestureEnable) { // 不操作
}else if (!_bannerGestureEnable && bannerGestureEnable){
self.collectionView.canCancelContentTouches = YES;
for (NSInteger i = 0; i < self.saveScrollViewGestures.count; i++) {
UIGestureRecognizer *gesture = self.saveScrollViewGestures[i];
[self.collectionView addGestureRecognizer:gesture];
}
}else if (_bannerGestureEnable && !bannerGestureEnable){
self.collectionView.canCancelContentTouches = NO;
for (UIGestureRecognizer *gesture in self.collectionView.gestureRecognizers) {
[self.collectionView removeGestureRecognizer:gesture];
}
}
_bannerGestureEnable = bannerGestureEnable;
}
- (void)setBannerImageViewContentMode:(UIViewContentMode)bannerImageViewContentMode{
_bannerImageViewContentMode = bannerImageViewContentMode;
self.backgroundImageView.contentMode = bannerImageViewContentMode;
}
- (NSInteger)repeatCount{
if (_repeatCount <= 0) {
return totalCollectionViewCellCount;
}else{
if (_repeatCount % 2 != 0) {
return _repeatCount + 1;
}else{
return _repeatCount;
}
}
}
#pragma mark - Getter
- (NSInteger)totalBannerItemsCount{
return self.cycleScrollEnable?(([self _imageDataSources].count > 1)?([self _imageDataSources].count * self.repeatCount):[self _imageDataSources].count):([self _imageDataSources].count);
}
- (BOOL)autoScroll{
if (self.showFooter) {
return NO;
}
return _autoScroll;
}
- (BOOL)cycleScrollEnable{
if (self.showFooter) {
return NO;
}
return _cycleScrollEnable;
}
- (UIFont *)titleFont{
if (!_titleFont) {
_titleFont = kMainFont;
}
return _titleFont;
}
- (UIColor *)titleTextColor{
if (!_titleTextColor) {
_titleTextColor = [UIColor whiteColor];
}
return _titleTextColor;
}
- (UIColor *)titleBackgroundColor{
if (!_titleBackgroundColor) {
_titleBackgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
}
return _titleBackgroundColor;
}
- (UIFont *)footerTitleFont{
if (!_footerTitleFont) {
_footerTitleFont = kFont12;
}
return _footerTitleFont;
}
- (UIColor *)footerTitleColor{
if (!_footerTitleColor) {
_footerTitleColor = [UIColor darkGrayColor];
}
return _footerTitleColor;
}
- (UIViewContentMode)bannerImageViewContentMode{
if (!_bannerImageViewContentMode) {
_bannerImageViewContentMode = UIViewContentModeScaleAspectFill;
}
return _bannerImageViewContentMode;
}
- (UIColor *)pageControlNormalColor{
if (!_pageControlNormalColor) {
_pageControlNormalColor = [UIColor lightGrayColor];
}
return _pageControlNormalColor;
}
- (UIColor *)pageControlHighlightColor{
if (!_pageControlHighlightColor) {
_pageControlHighlightColor = [UIColor whiteColor];
}
return _pageControlHighlightColor;
}
- (NSArray *)saveScrollViewGestures{
if (!_saveScrollViewGestures) {
_saveScrollViewGestures = self.collectionView.gestureRecognizers;
}
return _saveScrollViewGestures;
}
#pragma mark - layoutSubviews
- (void)layoutSubviews{
[super layoutSubviews];
self.dataSource = self.dataSource;
[super layoutSubviews];
self.flowLayout.itemSize = self.frame.size;
self.collectionView.frame = self.bounds;
if (self.collectionView.contentOffset.x == 0 && self.totalBannerItemsCount) {
NSInteger targetIndex = self.cycleScrollEnable?(self.totalBannerItemsCount * 0.5):(0);
[self _scrollBannerViewToSpecifiedPositionIndex:targetIndex animated:NO];
}
CGSize size = CGSizeZero;
if ([self.pageControl isKindOfClass:[YJHollowPageControl class]]) {
YJHollowPageControl *pageControl = (YJHollowPageControl *)_pageControl;
if (!(self.customPageControlNormalImage && self.customPageControlHighlightImage && CGSizeEqualToSize(kPageControlDotDefaultSize, self.pageControlDotSize))) {
pageControl.dotSize = self.pageControlDotSize;
}
size = [pageControl sizeForNumberOfPages:[self _imageDataSources].count];
} else {
size = CGSizeMake([self _imageDataSources].count * self.pageControlDotSize.width * 1.5, self.pageControlDotSize.height);
}
CGFloat x = (self.width_bannerView - size.width) * 0.5;
if (self.pageControlAliment == PageControlAlimentLeft) {
x = 0.0f;
}else if (self.pageControlAliment == PageControlAlimentCenter){
}else if (self.pageControlAliment == PageControlAlimentRight){
x = self.collectionView.width_bannerView - size.width;
}
CGFloat y = self.collectionView.height_bannerView - size.height;
if ([self.pageControl isKindOfClass:[YJHollowPageControl class]]) {
YJHollowPageControl *pageControl = (YJHollowPageControl *)_pageControl;
[pageControl sizeToFit];
}
CGRect pageControlFrame = CGRectMake(x, y, size.width, size.height);
if (self.pageControlAliment == PageControlAlimentLeft) {
pageControlFrame.origin.x += self.pageControlHorizontalEdgeMargin;
}else if (self.pageControlAliment == PageControlAlimentRight){
pageControlFrame.origin.x -= self.pageControlHorizontalEdgeMargin;
}
pageControlFrame.origin.y -= self.pageControlBottomMargin;
self.pageControl.frame = pageControlFrame;
self.pageControl.hidden = self.pageControlStyle == PageControlNone;
if (self.backgroundImageView) {
self.backgroundImageView.frame = self.bounds;
}
}
#pragma mark - Resolve compatibility optimization issues
- (void)willMoveToSuperview:(UIView *)newSuperview{
if (!newSuperview) {
[self invalidateTimer];
}
}
- (void)adjustBannerViewScrollToIndex:(NSInteger)index animated:(BOOL)animated{
if (self.showNewDatasource.count == 0) { return; }
if (index >= 0 && index < self.showNewDatasource.count) {
if (self.autoScroll) { [self invalidateTimer]; }
[self _scrollToIndex:((int)(self.totalBannerItemsCount * 0.5 + index)) animated:animated];
if (self.autoScroll) { [self _setupTimer]; }
}
}
- (void)adjustBannerViewWhenCardScreen{
long targetIndex = [self _currentPageIndex];
if (targetIndex < self.totalBannerItemsCount) {
[self _scrollBannerViewToSpecifiedPositionIndex:targetIndex animated:NO];
}
}
#pragma mark - UICollectionViewDataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
return self.totalBannerItemsCount;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
YJBannerViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:bannerViewCellId forIndexPath:indexPath];
long itemIndex = [self _getRealIndexFromCurrentCellIndex:indexPath.item];
// Custom Cell
if (self.dataSource && [self.dataSource respondsToSelector:@selector(bannerViewRegistCustomCellClass:)] && [self.dataSource bannerViewRegistCustomCellClass:self] && [self.dataSource respondsToSelector:@selector(bannerView:customCell:index:)] && [self.dataSource respondsToSelector:@selector(bannerView:reuseIdentifierForIndex:)]) {
NSString *reuseIdentifier = NSStringFromClass([self.dataSource bannerView:self reuseIdentifierForIndex:itemIndex]);
if (reuseIdentifier.length > 0) {
UICollectionViewCell *customCell = [collectionView dequeueReusableCellWithReuseIdentifier:reuseIdentifier forIndexPath:indexPath];
if ([self.dataSource bannerView:self customCell:customCell index:itemIndex]) {
return customCell;
}
}
}
NSString *imagePath = (itemIndex < [self _imageDataSources].count)?[self _imageDataSources][itemIndex]:nil;
NSString *title = (itemIndex < [self _titlesDataSources].count)?[self _titlesDataSources][itemIndex]:nil;
if (!cell.isConfigured) {
cell.titleLabelBackgroundColor = self.titleBackgroundColor;
cell.titleLabelHeight = self.titleHeight;
cell.titleLabelEdgeMargin = self.titleEdgeMargin;
cell.titleLabelTextAlignment = self.titleAlignment;
cell.titleLabelTextColor = self.titleTextColor;
cell.titleLabelTextFont = self.titleFont;
cell.showImageViewContentMode = self.bannerImageViewContentMode;
cell.clipsToBounds = YES;
cell.isConfigured = YES;
}
[cell cellWithSelectorString:self.bannerViewSelectorString imagePath:imagePath placeholderImage:self.placeholderImage title:title];
return cell;
}
// Setting Footer Size
- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForFooterInSection:(NSInteger)section{
return CGSizeMake((self.showFooter && [self _imageDataSources].count != 0)?[self _bannerViewFooterHeight]:0.0f, self.frame.size.height);
}
// Footer
- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath{
if(kind == UICollectionElementKindSectionFooter){
YJBannerViewFooter *footer = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:bannerViewFooterId forIndexPath:indexPath];
self.bannerFooter = footer;
footer.IndicateImageName = self.footerIndicateImageName;
footer.footerTitleFont = self.footerTitleFont;
footer.footerTitleColor = self.footerTitleColor;
footer.idleTitle = self.footerNormalTitle;
footer.triggerTitle = self.footerTriggerTitle;
footer.hidden = !(self.showFooter && [self _imageDataSources].count != 0);
return footer;
}else{
UICollectionReusableView *collectionHeaderView = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"HeaderView" forIndexPath:indexPath];
return collectionHeaderView;
}
}
#pragma mark - UIScrollViewDelegate
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
if (self.delegate && [self.delegate respondsToSelector:@selector(bannerView:didSelectItemAtIndex:)]) {
[self.delegate bannerView:self didSelectItemAtIndex:[self _getRealIndexFromCurrentCellIndex:indexPath.item]];
}
if (self.didSelectItemAtIndexBlock) {
self.didSelectItemAtIndexBlock([self _getRealIndexFromCurrentCellIndex:indexPath.item]);
}
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
if (![self _imageDataSources].count) return;
int itemIndex = [self _currentPageIndex];
int indexOnPageControl = [self _getRealIndexFromCurrentCellIndex:itemIndex];
// 手动退拽时左右两端
if (scrollView == self.collectionView && scrollView.isDragging && self.cycleScrollEnable) {
NSInteger targetIndex = self.totalBannerItemsCount * 0.5;
if (itemIndex == 0) { // top
[self _scrollBannerViewToSpecifiedPositionIndex:targetIndex animated:NO];
}else if (itemIndex == (self.totalBannerItemsCount - 1)){ // bottom
targetIndex -= 1;
[self _scrollBannerViewToSpecifiedPositionIndex:targetIndex animated:NO];
}
}
// pageControl
if ([self.pageControl isKindOfClass:[YJHollowPageControl class]]) {
YJHollowPageControl *pageControl = (YJHollowPageControl *)_pageControl;
pageControl.currentPage = indexOnPageControl;
} else {
UIPageControl *pageControl = (UIPageControl *)_pageControl;
pageControl.currentPage = indexOnPageControl;
}
// Footer
if (self.showFooter) {
static CGFloat lastOffset;
CGFloat footerDisplayOffset = (self.collectionView.contentOffset.x - (self.flowLayout.itemSize.width * (self.totalBannerItemsCount - 1)));
if (footerDisplayOffset > 0){
if (footerDisplayOffset > [self _bannerViewFooterHeight]) {
if (lastOffset > 0) return;
self.bannerFooter.state = YJBannerViewStatusTrigger;
} else {
if (lastOffset < 0) return;
self.bannerFooter.state = YJBannerViewStatusIdle;
}
lastOffset = footerDisplayOffset - [self _bannerViewFooterHeight];
}
}
// contentOffset
[self _saveInitializationContentOffsetJudgeZero:YES];
CGFloat contentOffset = 0.0f;
if (self.flowLayout.scrollDirection == UICollectionViewScrollDirectionHorizontal) {
contentOffset = self.collectionView.contentOffset.x;
} else {
contentOffset = self.collectionView.contentOffset.y;
}
CGFloat distance = fabs(self.lastContentOffset - contentOffset);
if (self.delegate && [self.delegate respondsToSelector:@selector(bannerView:didScrollCurrentIndex:contentOffset:)]) {
[self.delegate bannerView:self didScrollCurrentIndex:indexOnPageControl contentOffset:distance];
}
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView{
[self invalidateTimerWhenAutoScroll];
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
[self startTimerWhenAutoScroll];
if (self.showFooter) {
CGFloat footerDisplayOffset = (self.collectionView.contentOffset.x - (self.flowLayout.itemSize.width * (self.totalBannerItemsCount - 1)));
if (footerDisplayOffset > [self _bannerViewFooterHeight]) {
if (self.delegate && [self.delegate respondsToSelector:@selector(bannerViewFooterDidEndTrigger:)]) {
[self.delegate bannerViewFooterDidEndTrigger:self];
}
if (self.didEndTriggerFooterBlock) {
self.didEndTriggerFooterBlock();
}
}
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
[self scrollViewDidEndScrollingAnimation:self.collectionView];
}
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView{
if (![self _imageDataSources].count) return;
int itemIndex = [self _currentPageIndex];
int indexOnPageControl = [self _getRealIndexFromCurrentCellIndex:itemIndex];
if (self.delegate && [self.delegate respondsToSelector:@selector(bannerView:didScroll2Index:)]) {
[self.delegate bannerView:self didScroll2Index:indexOnPageControl];
}
if (self.didScroll2IndexBlock) {
self.didScroll2IndexBlock(indexOnPageControl);
}
[self _saveInitializationContentOffsetJudgeZero:NO];
}
#pragma mark - Private function method
/** install PageControl */
- (void)_setupPageControl{
if (_pageControl) [_pageControl removeFromSuperview];
if ([self _imageDataSources].count == 0) {return;}
if ([self _imageDataSources].count == 1) {return;}
int indexOnPageControl = [self _getRealIndexFromCurrentCellIndex:[self _currentPageIndex]];
switch (self.pageControlStyle) {
case PageControlNone:{
break;
}
case PageControlSystem:{
UIPageControl *pageControl = [[UIPageControl alloc] init];
pageControl.numberOfPages = [self _imageDataSources].count;
pageControl.currentPageIndicatorTintColor = self.pageControlHighlightColor;
pageControl.pageIndicatorTintColor = self.pageControlNormalColor;
pageControl.userInteractionEnabled = NO;
pageControl.currentPage = indexOnPageControl;
[self addSubview:pageControl];
_pageControl = pageControl;
break;
}
case PageControlHollow:{
YJHollowPageControl *pageControl = [[YJHollowPageControl alloc] init];
pageControl.numberOfPages = [self _imageDataSources].count;
pageControl.dotNormalColor = self.pageControlNormalColor;
pageControl.dotCurrentColor = self.pageControlHighlightColor;
pageControl.userInteractionEnabled = NO;
pageControl.resizeScale = 1.0;
pageControl.spacing = self.pageControlPadding;
pageControl.currentPage = indexOnPageControl;
[self addSubview:pageControl];
_pageControl = pageControl;
break;
}
case PageControlCustom:{
YJHollowPageControl *pageControl = [[YJHollowPageControl alloc] init];
pageControl.numberOfPages = [self _imageDataSources].count;
pageControl.dotNormalColor = self.pageControlNormalColor;
pageControl.dotCurrentColor = self.pageControlHighlightColor;
pageControl.userInteractionEnabled = NO;
pageControl.resizeScale = 1.0;
pageControl.spacing = self.pageControlPadding;
pageControl.currentPage = indexOnPageControl;
[self addSubview:pageControl];
_pageControl = pageControl;
if (self.customPageControlNormalImage) {
self.customPageControlNormalImage = self.customPageControlNormalImage;
}
if (self.customPageControlHighlightImage) {
self.customPageControlHighlightImage = self.customPageControlHighlightImage;
}
}
default:
break;
}
}
/** install Timer */
- (void)_setupTimer{
[self invalidateTimer];
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:self.autoDuration target:self selector:@selector(_automaticScrollAction) userInfo:nil repeats:YES];
_timer = timer;
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}
/** stop timer */
- (void)invalidateTimer{
[_timer invalidate];
_timer = nil;
}
/** stop timer api */
- (void)invalidateTimerWhenAutoScroll{
if (self.autoScroll) {
[self invalidateTimer];
}
}
/** restart timer api */
- (void)startTimerWhenAutoScroll{
if (self.autoScroll) {
[self _setupTimer];
}
}
- (void)_automaticScrollAction{
if (self.totalBannerItemsCount == 0) return;
int currentIndex = [self _currentPageIndex];
if (self.bannerViewScrollDirection == BannerViewDirectionLeft || self.bannerViewScrollDirection == BannerViewDirectionTop) {
[self _scrollToIndex:(currentIndex + 1) animated:YES];
}else if (self.bannerViewScrollDirection == BannerViewDirectionRight || self.bannerViewScrollDirection == BannerViewDirectionBottom){
if ((currentIndex - 1) < 0) { // 小于零
currentIndex = self.cycleScrollEnable?(self.totalBannerItemsCount * 0.5):(0);
[self _scrollBannerViewToSpecifiedPositionIndex:(currentIndex - 1) animated:NO];
}else{
[self _scrollToIndex:(currentIndex - 1) animated:YES];
}
}
}
- (void)_scrollToIndex:(int)targetIndex animated:(BOOL)animated{
if (targetIndex >= self.totalBannerItemsCount) { // 超过最大
targetIndex = self.cycleScrollEnable?(self.totalBannerItemsCount * 0.5):(0);
[self _scrollBannerViewToSpecifiedPositionIndex:targetIndex animated:NO];
}else{
[self _scrollBannerViewToSpecifiedPositionIndex:targetIndex animated:animated];
}
}
/** current page index */
- (int)_currentPageIndex{
if (self.collectionView.width_bannerView == 0 || self.collectionView.height_bannerView == 0) {return 0;}
int index = 0;
if (self.flowLayout.scrollDirection == UICollectionViewScrollDirectionHorizontal) {
index = (self.collectionView.contentOffset.x + self.flowLayout.itemSize.width * 0.5) / self.flowLayout.itemSize.width;
} else {
index = (self.collectionView.contentOffset.y + self.flowLayout.itemSize.height * 0.5) / self.flowLayout.itemSize.height;
}
return MAX(0, index);
}
/** current real index */
- (int)_getRealIndexFromCurrentCellIndex:(NSInteger)cellIndex{
return (int)cellIndex % [self _imageDataSources].count;
}
- (NSArray *)_imageDataSources{
return self.showNewDatasource;
}
/** Get new data from the proxy method */
- (NSArray *)_getImageDataSources{
if (self.dataSource && [self.dataSource respondsToSelector:@selector(bannerViewImages:)]) {
return [self.dataSource bannerViewImages:self];
}
return @[];
}
/** Get new data from the proxy method */
- (NSArray *)_titlesDataSources{
if (self.dataSource && [self.dataSource respondsToSelector:@selector(bannerViewTitles:)]) {
return [self.dataSource bannerViewTitles:self];
}
return @[];
}
/** Footer Height */
- (CGFloat)_bannerViewFooterHeight{
if (self.dataSource && [self.dataSource respondsToSelector:@selector(bannerViewFooterViewHeight:)]) {
return [self.dataSource bannerViewFooterViewHeight:self];
}
return BANNER_FOOTER_HEIGHT;
}
/** reload 时控制尾巴的显示和消失 */
- (void)_setFooterViewCanShow:(BOOL)showFooter{
if (showFooter) {
self.bannerViewScrollDirection = BannerViewDirectionLeft;
self.collectionView.contentInset = UIEdgeInsetsMake(0, 0, 0, -[self _bannerViewFooterHeight]);
}else{
self.collectionView.contentInset = UIEdgeInsetsZero;
}
if (self.bannerViewScrollDirection == BannerViewDirectionLeft) {
self.collectionView.alwaysBounceHorizontal = showFooter;
}else {
self.collectionView.accessibilityViewIsModal = showFooter;
}
}
/** Scroll the CollectionView to the specified location */
- (void)_scrollBannerViewToSpecifiedPositionIndex:(NSInteger)targetIndex animated:(BOOL)animated{
NSInteger itemCount = [self.collectionView numberOfItemsInSection:0];
if (targetIndex < itemCount) {
[self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:targetIndex?:0 inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:animated];
}
}
/** Save the current offset */
- (void)_saveInitializationContentOffsetJudgeZero:(BOOL)judgeZero{
if (self.collectionView.width_bannerView == 0 || self.collectionView.height_bannerView == 0) { return; }
if (judgeZero) {
if (self.lastContentOffset == 0) {
if (self.flowLayout.scrollDirection == UICollectionViewScrollDirectionHorizontal) {
self.lastContentOffset = self.collectionView.contentOffset.x;
} else {
self.lastContentOffset = self.collectionView.contentOffset.y;
}
}
}else{
if (self.flowLayout.scrollDirection == UICollectionViewScrollDirectionHorizontal) {
self.lastContentOffset = self.collectionView.contentOffset.x;
} else {
self.lastContentOffset = self.collectionView.contentOffset.y;
}
}
}
#pragma mark - Lazy
- (UIImageView *)backgroundImageView{
if (!_backgroundImageView) {
_backgroundImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
_backgroundImageView.contentMode = self.bannerImageViewContentMode;
_backgroundImageView.clipsToBounds = YES;
[self insertSubview:_backgroundImageView belowSubview:self.collectionView];
}
return _backgroundImageView;
}
- (UICollectionViewFlowLayout *)flowLayout{
if (!_flowLayout) {
_flowLayout = [[UICollectionViewFlowLayout alloc] init];
_flowLayout.minimumLineSpacing = 0.0f;
_flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
}
return _flowLayout;
}
- (YJBannerViewCollectionView *)collectionView{
if (!_collectionView) {
_collectionView = [[YJBannerViewCollectionView alloc] initWithFrame:self.bounds collectionViewLayout:self.flowLayout];
_collectionView.pagingEnabled = YES;
_collectionView.showsHorizontalScrollIndicator = NO;
_collectionView.showsVerticalScrollIndicator = NO;
_collectionView.backgroundColor = [UIColor clearColor];
[_collectionView registerClass:[YJBannerViewCell class] forCellWithReuseIdentifier:bannerViewCellId];
[_collectionView registerClass:[YJBannerViewFooter class] forSupplementaryViewOfKind:UICollectionElementKindSectionFooter withReuseIdentifier:bannerViewFooterId];
_collectionView.dataSource = self;
_collectionView.delegate = self;
_collectionView.scrollsToTop = NO;
}
return _collectionView;
}
- (void)dealloc {
self.collectionView.delegate = nil;
self.collectionView.dataSource = nil;
}
@end