You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

906 lines
33 KiB

//
// YJBannerView.m
// YJBannerViewDemo
//
// Created by YJHou on 2015/5/24.
// Copyright © 2015Address: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