小说绘上架版本
This commit is contained in:
+15
@@ -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
|
||||
+26
@@ -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
|
||||
+17
@@ -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
|
||||
+83
@@ -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
|
||||
+45
@@ -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
|
||||
+322
@@ -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 |
+19
@@ -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
|
||||
+53
@@ -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
|
||||
+24
@@ -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
|
||||
+149
@@ -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
|
||||
+13
@@ -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
|
||||
+13
@@ -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
|
||||
+26
@@ -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
|
||||
+125
@@ -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
|
||||
+19
@@ -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
|
||||
+85
@@ -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
|
||||
Reference in New Issue
Block a user