This commit is contained in:
启星
2025-08-08 10:49:36 +08:00
parent 6400cf78bb
commit b5ce3d580a
8780 changed files with 978183 additions and 0 deletions

22
Pods/SDCycleScrollView/LICENSE generated Executable file
View File

@@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2015 GSD_iOS
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

62
Pods/SDCycleScrollView/README.md generated Normal file
View File

@@ -0,0 +1,62 @@
# SDCycleScrollView新建QQ交流群185534916、675995250
## ☆☆☆ “iOS图片、文字轮播器” ☆☆☆
### 支持pod导入
pod 'SDCycleScrollView','>= 1.80'
### 更改记录:
2019.04.10 -- 适配SDWebImage 5.0.0
2017.11.26 -- 增加滚动到指定index接口
2017.10.28 -- 更新对SDWebImage的版本依赖
2017.06.23 -- 1.增加支持轮播自定义cell的代理方法 2.增加禁止拖动手势api
2016.05.27 -- 新增纯文字轮播、增加viewController在来回push时候出现的图片卡在中间的解决方案“解决viewWillAppear时出现时轮播图卡在一半的问题在控制器viewWillAppear时调用 adjustWhenControllerViewWillAppera”
2016.04.21 -- 修复自定义图片的pagecontrol刷新图片数据时崩溃bug设置单张图片时停止轮播
2016.03.31 -- 增加垂直方向滚动功能
2016.01.21 -- 修复加载时出现item size zero提示问题
2016.01.15 -- 兼容assets存放的本地图片
2016.01.06 -- 0.图片管理使用SDWebImage1.优化内存提升性能2.添加图片contentmode接口3.block监听点击接口4.滚动到某张图片监听5.增加自定义图片pageControl接口6.其他等等。其中有一处接口改动pagecontrol的小圆点自定义接口改为currentPageDotColor、pageDotColor、currentPageDotImage、pageDotImage。
### 无限循环自动图片轮播器(一步设置即可使用)
// 网络加载图片的轮播器
SDCycleScrollView *cycleScrollView = [cycleScrollViewWithFrame:frame delegate:delegate placeholderImage:placeholderImage];
cycleScrollView.imageURLStringsGroup = imagesURLStrings;
// 本地加载图片的轮播器
SDCycleScrollView *cycleScrollView = [SDCycleScrollView cycleScrollViewWithFrame: imagesGroup:图片数组];
---------------------------------------------------------------------------------------------------------------
## Q&A:
### 为什么我用这个轮播期会在顶部出现一块空白区域
以下是本库的使用者给出的一些解决方法放在这里供大家参考:
在iOS 7以后controller 会对其中唯一的scrollView或其子类调整内边距从而导致位置不准确。设置self.automaticallyAdjustsScrollViewInsets = NO;或者controller中放置不止一个scrollView或其子类时就不会出现这种问题。以上原因是我的猜测只要我设置了 self.automaticallyAdjustsScrollViewInsets = NO就没有那个问题了。
#PS:
如需更详细的设置,参考如下:
1. cycleScrollView.pageControlAliment = SDCycleScrollViewPageContolAlimentRight; // 设置pageControl居右默认居中
2. cycleScrollView.titlesGroup = 标题数组(数组元素个数必须和图片数组元素个数保持一致); // 如果设置title数组则会在图片下面添加标题
3. cycleScrollView.delegate = ; // 如需监听图片点击,请设置代理,实现代理方法
4. cycleScrollView.autoScrollTimeInterval = ;// 自定义轮播时间间隔
![](http://ww4.sinaimg.cn/bmiddle/9b8146edjw1esvytq7lwrg208p0fce82.gif)
![](http://cdn.cocimg.com/bbs/attachment/Fid_19/19_441660_d01407e9c4b63d1.gif)

View File

@@ -0,0 +1,24 @@
//
// TAAbstractDotView.h
// TAPageControl
//
// Created by Tanguy Aladenise on 2015-01-22.
// Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface TAAbstractDotView : UIView
/**
* A method call let view know which state appearance it should take. Active meaning it's current page. Inactive not the current page.
*
* @param active BOOL to tell if view is active or not
*/
- (void)changeActivityState:(BOOL)active;
@end

View File

@@ -0,0 +1,30 @@
//
// TAAbstractDotView.m
// TAPageControl
//
// Created by Tanguy Aladenise on 2015-01-22.
// Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
//
#import "TAAbstractDotView.h"
@implementation TAAbstractDotView
- (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

View File

@@ -0,0 +1,15 @@
//
// TAAnimatedDotView.h
// TAPageControl
//
// Created by Tanguy Aladenise on 2015-01-22.
// Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
//
#import "TAAbstractDotView.h"
@interface TAAnimatedDotView : TAAbstractDotView
@property (nonatomic, strong) UIColor *dotColor;
@end

View File

@@ -0,0 +1,88 @@
//
// TAAnimatedDotView.m
// TAPageControl
//
// Created by Tanguy Aladenise on 2015-01-22.
// Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
//
#import "TAAnimatedDotView.h"
static CGFloat const kAnimateDuration = 1;
@implementation TAAnimatedDotView
- (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)initialization
{
_dotColor = [UIColor whiteColor];
self.backgroundColor = [UIColor clearColor];
self.layer.cornerRadius = CGRectGetWidth(self.frame) / 2;
self.layer.borderColor = [UIColor whiteColor].CGColor;
self.layer.borderWidth = 2;
}
- (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->_dotColor;
self.transform = CGAffineTransformMakeScale(1.4, 1.4);
} completion:nil];
}
- (void)animateToDeactiveState
{
[UIView animateWithDuration:kAnimateDuration delay:0 usingSpringWithDamping:.5 initialSpringVelocity:0 options:UIViewAnimationOptionCurveLinear animations:^{
self.backgroundColor = [UIColor clearColor];
self.transform = CGAffineTransformIdentity;
} completion:nil];
}
@end

View File

@@ -0,0 +1,13 @@
//
// TADotView.h
// TAPageControl
//
// Created by Tanguy Aladenise on 2015-01-22.
// Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
//
#import "TAAbstractDotView.h"
@interface TADotView : TAAbstractDotView
@end

View File

@@ -0,0 +1,63 @@
//
// TADotView.m
// TAPageControl
//
// Created by Tanguy Aladenise on 2015-01-22.
// Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
//
#import "TADotView.h"
@implementation TADotView
- (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)initialization
{
self.backgroundColor = [UIColor clearColor];
self.layer.cornerRadius = CGRectGetWidth(self.frame) / 2;
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

View File

@@ -0,0 +1,106 @@
//
// TAPageControl.h
// TAPageControl
//
// Created by Tanguy Aladenise on 2015-01-21.
// Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
//
#import <UIKit/UIKit.h>
@protocol TAPageControlDelegate;
@interface TAPageControl : UIControl
/**
* Dot view customization properties
*/
/**
* The Class of your custom UIView, make sure to respect the TAAbstractDotView class.
*/
@property (nonatomic) Class dotViewClass;
/**
* UIImage to represent a dot.
*/
@property (nonatomic) UIImage *dotImage;
/**
* UIImage to represent current page dot.
*/
@property (nonatomic) UIImage *currentDotImage;
/**
* Dot size for dot views. Default is 8 by 8.
*/
@property (nonatomic) CGSize dotSize;
@property (nonatomic, strong) UIColor *dotColor;
/**
* Spacing between two dot views. Default is 8.
*/
@property (nonatomic) NSInteger spacingBetweenDots;
/**
* Page control setup properties
*/
/**
* Delegate for TAPageControl
*/
@property(nonatomic,assign) id<TAPageControlDelegate> delegate;
/**
* Number of pages for control. Default is 0.
*/
@property (nonatomic) NSInteger numberOfPages;
/**
* Current page on which control is active. Default is 0.
*/
@property (nonatomic) NSInteger currentPage;
/**
* Hide the control if there is only one page. Default is NO.
*/
@property (nonatomic) BOOL hidesForSinglePage;
/**
* Let the control know if should grow bigger by keeping center, or just get longer (right side expanding). By default YES.
*/
@property (nonatomic) BOOL shouldResizeFromCenter;
/**
* Return the minimum size required to display control properly for the given page count.
*
* @param pageCount Number of dots that will require display
*
* @return The CGSize being the minimum size required.
*/
- (CGSize)sizeForNumberOfPages:(NSInteger)pageCount;
@end
@protocol TAPageControlDelegate <NSObject>
@optional
- (void)TAPageControl:(TAPageControl *)pageControl didSelectPageAtIndex:(NSInteger)index;
@end

View File

@@ -0,0 +1,364 @@
//
// TAPageControl.m
// TAPageControl
//
// Created by Tanguy Aladenise on 2015-01-21.
// Copyright (c) 2015 Tanguy Aladenise. All rights reserved.
//
#import "TAPageControl.h"
#import "TAAbstractDotView.h"
#import "TAAnimatedDotView.h"
#import "TADotView.h"
/**
* Default number of pages for initialization
*/
static NSInteger const kDefaultNumberOfPages = 0;
/**
* Default current page for initialization
*/
static NSInteger const kDefaultCurrentPage = 0;
/**
* Default setting for hide for single page feature. For initialization
*/
static BOOL const kDefaultHideForSinglePage = NO;
/**
* Default setting for shouldResizeFromCenter. For initialiation
*/
static BOOL const kDefaultShouldResizeFromCenter = YES;
/**
* Default spacing between dots
*/
static NSInteger const kDefaultSpacingBetweenDots = 8;
/**
* Default dot size
*/
static CGSize const kDefaultDotSize = {8, 8};
@interface TAPageControl()
/**
* Array of dot views for reusability and touch events.
*/
@property (strong, nonatomic) NSMutableArray *dots;
@end
@implementation TAPageControl
#pragma mark - Lifecycle
- (id)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;
}
/**
* Default setup when initiating control
*/
- (void)initialization
{
self.dotViewClass = [TAAnimatedDotView class];
self.spacingBetweenDots = 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(TAPageControl:didSelectPageAtIndex:)]) {
[self.delegate TAPageControl:self didSelectPageAtIndex:index];
}
}
}
#pragma mark - Layout
/**
* Resizes and moves the receiver view so it just encloses its subviews.
*/
- (void)sizeToFit
{
[self updateFrame:YES];
}
- (CGSize)sizeForNumberOfPages:(NSInteger)pageCount
{
return CGSizeMake((self.dotSize.width + self.spacingBetweenDots) * pageCount - self.spacingBetweenDots , self.dotSize.height);
}
/**
* Will update dots display and frame. Reuse existing views or instantiate one if required. Update their position in case frame changed.
*/
- (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 objectAtIndex:i];
} else {
dot = [self generateDotView];
}
[self updateDotFrame:dot atIndex:i];
}
[self changeActivity:YES atIndex:self.currentPage];
[self hideForSinglePage];
}
/**
* Update frame control to fit current number of pages. It will apply required size if authorize and required.
*
* @param overrideExistingFrame BOOL to allow frame to be overriden. Meaning the required size will be apply no mattter what.
*/
- (void)updateFrame:(BOOL)overrideExistingFrame
{
CGPoint center = self.center;
CGSize requiredSize = [self sizeForNumberOfPages:self.numberOfPages];
// We apply requiredSize only if authorize to and necessary
if (overrideExistingFrame || ((CGRectGetWidth(self.frame) < requiredSize.width || CGRectGetHeight(self.frame) < requiredSize.height) && !overrideExistingFrame)) {
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.spacingBetweenDots) * 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);
}
#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:[TAAnimatedDotView class]] && self.dotColor) {
((TAAnimatedDotView *)dotView).dotColor = self.dotColor;
}
} else {
dotView = [[UIImageView alloc] initWithImage:self.dotImage];
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) {
TAAbstractDotView *abstractDotView = (TAAbstractDotView *)[self.dots objectAtIndex:index];
if ([abstractDotView respondsToSelector:@selector(changeActivityState:)]) {
[abstractDotView changeActivityState:active];
} else {
NSLog(@"Custom view : %@ must implement an 'changeActivityState' method or you can subclass %@ to help you.", self.dotViewClass, [TAAbstractDotView class]);
}
} else if (self.dotImage && self.currentDotImage) {
UIImageView *dotView = (UIImageView *)[self.dots objectAtIndex:index];
dotView.image = (active) ? self.currentDotImage : self.dotImage;
}
}
- (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)setSpacingBetweenDots:(NSInteger)spacingBetweenDots
{
_spacingBetweenDots = spacingBetweenDots;
[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)setDotImage:(UIImage *)dotImage
{
_dotImage = dotImage;
[self resetDotViews];
self.dotViewClass = nil;
}
- (void)setCurrentDotImage:(UIImage *)currentDotimage
{
_currentDotImage = currentDotimage;
[self resetDotViews];
self.dotViewClass = nil;
}
- (void)setDotViewClass:(Class)dotViewClass
{
_dotViewClass = dotViewClass;
self.dotSize = CGSizeZero;
[self resetDotViews];
}
#pragma mark - Getters
- (NSMutableArray *)dots
{
if (!_dots) {
_dots = [[NSMutableArray alloc] init];
}
return _dots;
}
- (CGSize)dotSize
{
// Dot size logic depending on the source of the dot view
if (self.dotImage && CGSizeEqualToSize(_dotSize, CGSizeZero)) {
_dotSize = self.dotImage.size;
} else if (self.dotViewClass && CGSizeEqualToSize(_dotSize, CGSizeZero)) {
_dotSize = kDefaultDotSize;
return _dotSize;
}
return _dotSize;
}
@end

View File

@@ -0,0 +1,51 @@
//
// SDCollectionViewCell.h
// SDCycleScrollView
//
// Created by aier on 15-3-22.
// Copyright (c) 2015年 GSD. All rights reserved.
//
/*
*********************************************************************************
*
* 🌟🌟🌟 新建SDCycleScrollView交流QQ群185534916 🌟🌟🌟
*
* 在您使用此自动轮播库的过程中如果出现bug请及时以以下任意一种方式联系我们我们会及时修复bug并
* 帮您解决问题。
* 新浪微博:GSD_iOS
* Email : gsdios@126.com
* GitHub: https://github.com/gsdios
*
* 另我的自动布局库SDAutoLayout
* 一行代码搞定自动布局支持Cell和Tableview高度自适应Label和ScrollView内容自适应致力于
* 做最简单易用的AutoLayout库。
* 视频教程http://www.letv.com/ptv/vplay/24038772.html
* 用法示例https://github.com/gsdios/SDAutoLayout/blob/master/README.md
* GitHubhttps://github.com/gsdios/SDAutoLayout
*********************************************************************************
*/
#import <UIKit/UIKit.h>
@interface SDCollectionViewCell : UICollectionViewCell
@property (weak, nonatomic) UIImageView *imageView;
@property (copy, nonatomic) NSString *title;
@property (nonatomic, strong) UIColor *titleLabelTextColor;
@property (nonatomic, strong) UIFont *titleLabelTextFont;
@property (nonatomic, strong) UIColor *titleLabelBackgroundColor;
@property (nonatomic, assign) CGFloat titleLabelHeight;
@property (nonatomic, assign) NSTextAlignment titleLabelTextAlignment;
@property (nonatomic, assign) BOOL hasConfigured;
/** 只展示文字轮播 */
@property (nonatomic, assign) BOOL onlyDisplayText;
@end

View File

@@ -0,0 +1,116 @@
//
// SDCollectionViewCell.m
// SDCycleScrollView
//
// Created by aier on 15-3-22.
// Copyright (c) 2015 GSD. All rights reserved.
//
/*
*********************************************************************************
*
* 🌟🌟🌟 SDCycleScrollViewQQ185534916 🌟🌟🌟
*
* 使bugbug
*
* :GSD_iOS
* Email : gsdios@126.com
* GitHub: https://github.com/gsdios
*
* SDAutoLayout
* CellTableviewLabelScrollView
* AutoLayout
* http://www.letv.com/ptv/vplay/24038772.html
* https://github.com/gsdios/SDAutoLayout/blob/master/README.md
* GitHubhttps://github.com/gsdios/SDAutoLayout
*********************************************************************************
*/
#import "SDCollectionViewCell.h"
#import "UIView+SDExtension.h"
@implementation SDCollectionViewCell
{
__weak UILabel *_titleLabel;
}
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self setupImageView];
[self setupTitleLabel];
}
return self;
}
- (void)setTitleLabelBackgroundColor:(UIColor *)titleLabelBackgroundColor
{
_titleLabelBackgroundColor = titleLabelBackgroundColor;
_titleLabel.backgroundColor = titleLabelBackgroundColor;
}
- (void)setTitleLabelTextColor:(UIColor *)titleLabelTextColor
{
_titleLabelTextColor = titleLabelTextColor;
_titleLabel.textColor = titleLabelTextColor;
}
- (void)setTitleLabelTextFont:(UIFont *)titleLabelTextFont
{
_titleLabelTextFont = titleLabelTextFont;
_titleLabel.font = titleLabelTextFont;
}
- (void)setupImageView
{
UIImageView *imageView = [[UIImageView alloc] init];
_imageView = imageView;
[self.contentView addSubview:imageView];
}
- (void)setupTitleLabel
{
UILabel *titleLabel = [[UILabel alloc] init];
_titleLabel = titleLabel;
_titleLabel.hidden = YES;
[self.contentView addSubview:titleLabel];
}
- (void)setTitle:(NSString *)title
{
_title = [title copy];
_titleLabel.text = [NSString stringWithFormat:@" %@", title];
if (_titleLabel.hidden) {
_titleLabel.hidden = NO;
}
}
-(void)setTitleLabelTextAlignment:(NSTextAlignment)titleLabelTextAlignment
{
_titleLabelTextAlignment = titleLabelTextAlignment;
_titleLabel.textAlignment = titleLabelTextAlignment;
}
- (void)layoutSubviews
{
[super layoutSubviews];
if (self.onlyDisplayText) {
_titleLabel.frame = self.bounds;
} else {
_imageView.frame = self.bounds;
CGFloat titleLabelW = self.sd_width;
CGFloat titleLabelH = _titleLabelHeight;
CGFloat titleLabelX = 0;
CGFloat titleLabelY = self.sd_height - titleLabelH;
_titleLabel.frame = CGRectMake(titleLabelX, titleLabelY, titleLabelW, titleLabelH);
}
}
@end

View File

@@ -0,0 +1,211 @@
//
// SDCycleScrollView.h
// SDCycleScrollView
//
// Created by aier on 15-3-22.
// Copyright (c) 2015年 GSD. All rights reserved.
//
/*
*********************************************************************************
*
* 🌟🌟🌟 新建SDCycleScrollView交流QQ群185534916 🌟🌟🌟
*
* 在您使用此自动轮播库的过程中如果出现bug请及时以以下任意一种方式联系我们我们会及时修复bug并
* 帮您解决问题。
* 新浪微博:GSD_iOS
* Email : gsdios@126.com
* GitHub: https://github.com/gsdios
*
* 另我的自动布局库SDAutoLayout
* 一行代码搞定自动布局支持Cell和Tableview高度自适应Label和ScrollView内容自适应致力于
* 做最简单易用的AutoLayout库。
* 视频教程http://www.letv.com/ptv/vplay/24038772.html
* 用法示例https://github.com/gsdios/SDAutoLayout/blob/master/README.md
* GitHubhttps://github.com/gsdios/SDAutoLayout
*********************************************************************************
*/
/*
* 当前版本为1.62
* 更新日期2016.04.21
*/
#import <UIKit/UIKit.h>
typedef enum {
SDCycleScrollViewPageContolAlimentRight,
SDCycleScrollViewPageContolAlimentCenter
} SDCycleScrollViewPageContolAliment;
typedef enum {
SDCycleScrollViewPageContolStyleClassic, // 系统自带经典样式
SDCycleScrollViewPageContolStyleAnimated, // 动画效果pagecontrol
SDCycleScrollViewPageContolStyleNone // 不显示pagecontrol
} SDCycleScrollViewPageContolStyle;
@class SDCycleScrollView;
@protocol SDCycleScrollViewDelegate <NSObject>
@optional
/** 点击图片回调 */
- (void)cycleScrollView:(SDCycleScrollView *)cycleScrollView didSelectItemAtIndex:(NSInteger)index;
/** 图片滚动回调 */
- (void)cycleScrollView:(SDCycleScrollView *)cycleScrollView didScrollToIndex:(NSInteger)index;
// 不需要自定义轮播cell的请忽略以下两个的代理方法
// ========== 轮播自定义cell ==========
/** 如果你需要自定义cell样式请在实现此代理方法返回你的自定义cell的class。 */
- (Class)customCollectionViewCellClassForCycleScrollView:(SDCycleScrollView *)view;
/** 如果你需要自定义cell样式请在实现此代理方法返回你的自定义cell的Nib。 */
- (UINib *)customCollectionViewCellNibForCycleScrollView:(SDCycleScrollView *)view;
/** 如果你自定义了cell样式请在实现此代理方法为你的cell填充数据以及其它一系列设置 */
- (void)setupCustomCell:(UICollectionViewCell *)cell forIndex:(NSInteger)index cycleScrollView:(SDCycleScrollView *)view;
@end
@interface SDCycleScrollView : UIView
/** 初始轮播图(推荐使用) */
+ (instancetype)cycleScrollViewWithFrame:(CGRect)frame delegate:(id<SDCycleScrollViewDelegate>)delegate placeholderImage:(UIImage *)placeholderImage;
+ (instancetype)cycleScrollViewWithFrame:(CGRect)frame imageURLStringsGroup:(NSArray *)imageURLStringsGroup;
/** 本地图片轮播初始化方式 */
+ (instancetype)cycleScrollViewWithFrame:(CGRect)frame imageNamesGroup:(NSArray *)imageNamesGroup;
/** 本地图片轮播初始化方式2,infiniteLoop:是否无限循环 */
+ (instancetype)cycleScrollViewWithFrame:(CGRect)frame shouldInfiniteLoop:(BOOL)infiniteLoop imageNamesGroup:(NSArray *)imageNamesGroup;
////////////////////// 数据源API //////////////////////
/** 网络图片 url string 数组 */
@property (nonatomic, strong) NSArray *imageURLStringsGroup;
/** 每张图片对应要显示的文字数组 */
@property (nonatomic, strong) NSArray *titlesGroup;
/** 本地图片数组 */
@property (nonatomic, strong) NSArray *localizationImageNamesGroup;
////////////////////// 滚动控制API //////////////////////
/** 自动滚动间隔时间,默认2s */
@property (nonatomic, assign) CGFloat autoScrollTimeInterval;
/** 是否无限循环,默认Yes */
@property (nonatomic,assign) BOOL infiniteLoop;
/** 是否自动滚动,默认Yes */
@property (nonatomic,assign) BOOL autoScroll;
/** 图片滚动方向,默认为水平滚动 */
@property (nonatomic, assign) UICollectionViewScrollDirection scrollDirection;
@property (nonatomic, weak) id<SDCycleScrollViewDelegate> delegate;
/** block方式监听点击 */
@property (nonatomic, copy) void (^clickItemOperationBlock)(NSInteger currentIndex);
/** block方式监听滚动 */
@property (nonatomic, copy) void (^itemDidScrollOperationBlock)(NSInteger currentIndex);
/** 可以调用此方法手动控制滚动到哪一个index */
- (void)makeScrollViewScrollToIndex:(NSInteger)index;
/** 解决viewWillAppear时出现时轮播图卡在一半的问题在控制器viewWillAppear时调用此方法 */
- (void)adjustWhenControllerViewWillAppera;
////////////////////// 自定义样式API //////////////////////
/** 轮播图片的ContentMode默认为 UIViewContentModeScaleToFill */
@property (nonatomic, assign) UIViewContentMode bannerImageViewContentMode;
/** 占位图,用于网络未加载到图片时 */
@property (nonatomic, strong) UIImage *placeholderImage;
/** 是否显示分页控件 */
@property (nonatomic, assign) BOOL showPageControl;
/** 是否在只有一张图时隐藏pagecontrol默认为YES */
@property(nonatomic) BOOL hidesForSinglePage;
/** 只展示文字轮播 */
@property (nonatomic, assign) BOOL onlyDisplayText;
/** pagecontrol 样式,默认为动画样式 */
@property (nonatomic, assign) SDCycleScrollViewPageContolStyle pageControlStyle;
/** 分页控件位置 */
@property (nonatomic, assign) SDCycleScrollViewPageContolAliment pageControlAliment;
/** 分页控件距离轮播图的底部间距(在默认间距基础上)的偏移量 */
@property (nonatomic, assign) CGFloat pageControlBottomOffset;
/** 分页控件距离轮播图的右边间距(在默认间距基础上)的偏移量 */
@property (nonatomic, assign) CGFloat pageControlRightOffset;
/** 分页控件小圆标大小 */
@property (nonatomic, assign) CGSize pageControlDotSize;
/** 当前分页控件小圆标颜色 */
@property (nonatomic, strong) UIColor *currentPageDotColor;
/** 其他分页控件小圆标颜色 */
@property (nonatomic, strong) UIColor *pageDotColor;
/** 当前分页控件小圆标图片 */
@property (nonatomic, strong) UIImage *currentPageDotImage;
/** 其他分页控件小圆标图片 */
@property (nonatomic, strong) UIImage *pageDotImage;
/** 轮播文字label字体颜色 */
@property (nonatomic, strong) UIColor *titleLabelTextColor;
/** 轮播文字label字体大小 */
@property (nonatomic, strong) UIFont *titleLabelTextFont;
/** 轮播文字label背景颜色 */
@property (nonatomic, strong) UIColor *titleLabelBackgroundColor;
/** 轮播文字label高度 */
@property (nonatomic, assign) CGFloat titleLabelHeight;
/** 轮播文字label对齐方式 */
@property (nonatomic, assign) NSTextAlignment titleLabelTextAlignment;
/** 滚动手势禁用(文字轮播较实用) */
- (void)disableScrollGesture;
////////////////////// 清除缓存API //////////////////////
/** 清除图片缓存此次升级后统一使用SDWebImage管理图片加载和缓存 */
+ (void)clearImagesCache;
/** 清除图片缓存(兼容旧版本方法) */
- (void)clearCache;
@end

View File

@@ -0,0 +1,700 @@
//
// SDCycleScrollView.m
// SDCycleScrollView
//
// Created by aier on 15-3-22.
// Copyright (c) 2015 GSD. All rights reserved.
//
/*
*********************************************************************************
*
* 🌟🌟🌟 SDCycleScrollViewQQ185534916 🌟🌟🌟
*
* 使bugbug
*
* :GSD_iOS
* Email : gsdios@126.com
* GitHub: https://github.com/gsdios
*
* SDAutoLayout
* CellTableviewLabelScrollView
* AutoLayout
* http://www.letv.com/ptv/vplay/24038772.html
* https://github.com/gsdios/SDAutoLayout/blob/master/README.md
* GitHubhttps://github.com/gsdios/SDAutoLayout
*********************************************************************************
*/
#import "SDCycleScrollView.h"
#import "SDCollectionViewCell.h"
#import "UIView+SDExtension.h"
#import "TAPageControl.h"
#import "SDWebImageManager.h"
#import "UIImageView+WebCache.h"
#define kCycleScrollViewInitialPageControlDotSize CGSizeMake(10, 10)
NSString * const ID = @"SDCycleScrollViewCell";
@interface SDCycleScrollView () <UICollectionViewDataSource, UICollectionViewDelegate>
@property (nonatomic, weak) UICollectionView *mainView; // collectionView
@property (nonatomic, weak) UICollectionViewFlowLayout *flowLayout;
@property (nonatomic, strong) NSArray *imagePathsGroup;
@property (nonatomic, weak) NSTimer *timer;
@property (nonatomic, assign) NSInteger totalItemsCount;
@property (nonatomic, weak) UIControl *pageControl;
@property (nonatomic, strong) UIImageView *backgroundImageView; // imageURLs
@end
@implementation SDCycleScrollView
- (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
[self initialization];
[self setupMainView];
}
return self;
}
- (void)awakeFromNib
{
[super awakeFromNib];
[self initialization];
[self setupMainView];
}
- (void)initialization
{
_pageControlAliment = SDCycleScrollViewPageContolAlimentCenter;
_autoScrollTimeInterval = 2.0;
_titleLabelTextColor = [UIColor whiteColor];
_titleLabelTextFont= [UIFont systemFontOfSize:14];
_titleLabelBackgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];
_titleLabelHeight = 30;
_titleLabelTextAlignment = NSTextAlignmentLeft;
_autoScroll = YES;
_infiniteLoop = YES;
_showPageControl = YES;
_pageControlDotSize = kCycleScrollViewInitialPageControlDotSize;
_pageControlBottomOffset = 0;
_pageControlRightOffset = 0;
_pageControlStyle = SDCycleScrollViewPageContolStyleClassic;
_hidesForSinglePage = YES;
_currentPageDotColor = [UIColor whiteColor];
_pageDotColor = [UIColor lightGrayColor];
_bannerImageViewContentMode = UIViewContentModeScaleToFill;
self.backgroundColor = [UIColor lightGrayColor];
}
+ (instancetype)cycleScrollViewWithFrame:(CGRect)frame imageNamesGroup:(NSArray *)imageNamesGroup
{
SDCycleScrollView *cycleScrollView = [[self alloc] initWithFrame:frame];
cycleScrollView.localizationImageNamesGroup = [NSMutableArray arrayWithArray:imageNamesGroup];
return cycleScrollView;
}
+ (instancetype)cycleScrollViewWithFrame:(CGRect)frame shouldInfiniteLoop:(BOOL)infiniteLoop imageNamesGroup:(NSArray *)imageNamesGroup
{
SDCycleScrollView *cycleScrollView = [[self alloc] initWithFrame:frame];
cycleScrollView.infiniteLoop = infiniteLoop;
cycleScrollView.localizationImageNamesGroup = [NSMutableArray arrayWithArray:imageNamesGroup];
return cycleScrollView;
}
+ (instancetype)cycleScrollViewWithFrame:(CGRect)frame imageURLStringsGroup:(NSArray *)imageURLsGroup
{
SDCycleScrollView *cycleScrollView = [[self alloc] initWithFrame:frame];
cycleScrollView.imageURLStringsGroup = [NSMutableArray arrayWithArray:imageURLsGroup];
return cycleScrollView;
}
+ (instancetype)cycleScrollViewWithFrame:(CGRect)frame delegate:(id<SDCycleScrollViewDelegate>)delegate placeholderImage:(UIImage *)placeholderImage
{
SDCycleScrollView *cycleScrollView = [[self alloc] initWithFrame:frame];
cycleScrollView.delegate = delegate;
cycleScrollView.placeholderImage = placeholderImage;
return cycleScrollView;
}
// collectionView
- (void)setupMainView
{
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
flowLayout.minimumLineSpacing = 0;
flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
_flowLayout = flowLayout;
UICollectionView *mainView = [[UICollectionView alloc] initWithFrame:self.bounds collectionViewLayout:flowLayout];
mainView.backgroundColor = [UIColor clearColor];
mainView.pagingEnabled = YES;
mainView.showsHorizontalScrollIndicator = NO;
mainView.showsVerticalScrollIndicator = NO;
[mainView registerClass:[SDCollectionViewCell class] forCellWithReuseIdentifier:ID];
mainView.dataSource = self;
mainView.delegate = self;
mainView.scrollsToTop = NO;
[self addSubview:mainView];
_mainView = mainView;
}
#pragma mark - properties
- (void)setDelegate:(id<SDCycleScrollViewDelegate>)delegate
{
_delegate = delegate;
if ([self.delegate respondsToSelector:@selector(customCollectionViewCellClassForCycleScrollView:)] && [self.delegate customCollectionViewCellClassForCycleScrollView:self]) {
[self.mainView registerClass:[self.delegate customCollectionViewCellClassForCycleScrollView:self] forCellWithReuseIdentifier:ID];
}else if ([self.delegate respondsToSelector:@selector(customCollectionViewCellNibForCycleScrollView:)] && [self.delegate customCollectionViewCellNibForCycleScrollView:self]) {
[self.mainView registerNib:[self.delegate customCollectionViewCellNibForCycleScrollView:self] forCellWithReuseIdentifier:ID];
}
}
- (void)setPlaceholderImage:(UIImage *)placeholderImage
{
_placeholderImage = placeholderImage;
if (!self.backgroundImageView) {
UIImageView *bgImageView = [UIImageView new];
bgImageView.contentMode = UIViewContentModeScaleAspectFit;
[self insertSubview:bgImageView belowSubview:self.mainView];
self.backgroundImageView = bgImageView;
}
self.backgroundImageView.image = placeholderImage;
}
- (void)setPageControlDotSize:(CGSize)pageControlDotSize
{
_pageControlDotSize = pageControlDotSize;
[self setupPageControl];
if ([self.pageControl isKindOfClass:[TAPageControl class]]) {
TAPageControl *pageContol = (TAPageControl *)_pageControl;
pageContol.dotSize = pageControlDotSize;
}
}
- (void)setShowPageControl:(BOOL)showPageControl
{
_showPageControl = showPageControl;
_pageControl.hidden = !showPageControl;
}
- (void)setCurrentPageDotColor:(UIColor *)currentPageDotColor
{
_currentPageDotColor = currentPageDotColor;
if ([self.pageControl isKindOfClass:[TAPageControl class]]) {
TAPageControl *pageControl = (TAPageControl *)_pageControl;
pageControl.dotColor = currentPageDotColor;
} else {
UIPageControl *pageControl = (UIPageControl *)_pageControl;
pageControl.currentPageIndicatorTintColor = currentPageDotColor;
}
}
- (void)setPageDotColor:(UIColor *)pageDotColor
{
_pageDotColor = pageDotColor;
if ([self.pageControl isKindOfClass:[UIPageControl class]]) {
UIPageControl *pageControl = (UIPageControl *)_pageControl;
pageControl.pageIndicatorTintColor = pageDotColor;
}
}
- (void)setCurrentPageDotImage:(UIImage *)currentPageDotImage
{
_currentPageDotImage = currentPageDotImage;
if (self.pageControlStyle != SDCycleScrollViewPageContolStyleAnimated) {
self.pageControlStyle = SDCycleScrollViewPageContolStyleAnimated;
}
[self setCustomPageControlDotImage:currentPageDotImage isCurrentPageDot:YES];
}
- (void)setPageDotImage:(UIImage *)pageDotImage
{
_pageDotImage = pageDotImage;
if (self.pageControlStyle != SDCycleScrollViewPageContolStyleAnimated) {
self.pageControlStyle = SDCycleScrollViewPageContolStyleAnimated;
}
[self setCustomPageControlDotImage:pageDotImage isCurrentPageDot:NO];
}
- (void)setCustomPageControlDotImage:(UIImage *)image isCurrentPageDot:(BOOL)isCurrentPageDot
{
if (!image || !self.pageControl) return;
if ([self.pageControl isKindOfClass:[TAPageControl class]]) {
TAPageControl *pageControl = (TAPageControl *)_pageControl;
if (isCurrentPageDot) {
pageControl.currentDotImage = image;
} else {
pageControl.dotImage = image;
}
}
}
- (void)setInfiniteLoop:(BOOL)infiniteLoop
{
_infiniteLoop = infiniteLoop;
if (self.imagePathsGroup.count) {
self.imagePathsGroup = self.imagePathsGroup;
}
}
-(void)setAutoScroll:(BOOL)autoScroll{
_autoScroll = autoScroll;
[self invalidateTimer];
if (_autoScroll) {
[self setupTimer];
}
}
- (void)setScrollDirection:(UICollectionViewScrollDirection)scrollDirection
{
_scrollDirection = scrollDirection;
_flowLayout.scrollDirection = scrollDirection;
}
- (void)setAutoScrollTimeInterval:(CGFloat)autoScrollTimeInterval
{
_autoScrollTimeInterval = autoScrollTimeInterval;
[self setAutoScroll:self.autoScroll];
}
- (void)setPageControlStyle:(SDCycleScrollViewPageContolStyle)pageControlStyle
{
_pageControlStyle = pageControlStyle;
[self setupPageControl];
}
- (void)setImagePathsGroup:(NSArray *)imagePathsGroup
{
[self invalidateTimer];
_imagePathsGroup = imagePathsGroup;
_totalItemsCount = self.infiniteLoop ? self.imagePathsGroup.count * 100 : self.imagePathsGroup.count;
if (imagePathsGroup.count > 1) { // !=1 count == 0
self.mainView.scrollEnabled = YES;
[self setAutoScroll:self.autoScroll];
} else {
self.mainView.scrollEnabled = NO;
[self invalidateTimer];
}
[self setupPageControl];
[self.mainView reloadData];
}
- (void)setImageURLStringsGroup:(NSArray *)imageURLStringsGroup
{
_imageURLStringsGroup = imageURLStringsGroup;
NSMutableArray *temp = [NSMutableArray new];
[_imageURLStringsGroup enumerateObjectsUsingBlock:^(NSString * obj, NSUInteger idx, BOOL * stop) {
NSString *urlString;
if ([obj isKindOfClass:[NSString class]]) {
urlString = obj;
} else if ([obj isKindOfClass:[NSURL class]]) {
NSURL *url = (NSURL *)obj;
urlString = [url absoluteString];
}
if (urlString) {
[temp addObject:urlString];
}
}];
self.imagePathsGroup = [temp copy];
}
- (void)setLocalizationImageNamesGroup:(NSArray *)localizationImageNamesGroup
{
_localizationImageNamesGroup = localizationImageNamesGroup;
self.imagePathsGroup = [localizationImageNamesGroup copy];
}
- (void)setTitlesGroup:(NSArray *)titlesGroup
{
_titlesGroup = titlesGroup;
if (self.onlyDisplayText) {
NSMutableArray *temp = [NSMutableArray new];
for (int i = 0; i < _titlesGroup.count; i++) {
[temp addObject:@""];
}
self.backgroundColor = [UIColor clearColor];
self.imageURLStringsGroup = [temp copy];
}
}
- (void)disableScrollGesture {
self.mainView.canCancelContentTouches = NO;
for (UIGestureRecognizer *gesture in self.mainView.gestureRecognizers) {
if ([gesture isKindOfClass:[UIPanGestureRecognizer class]]) {
[self.mainView removeGestureRecognizer:gesture];
}
}
}
#pragma mark - actions
- (void)setupTimer
{
[self invalidateTimer]; //
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:self.autoScrollTimeInterval target:self selector:@selector(automaticScroll) userInfo:nil repeats:YES];
_timer = timer;
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
}
- (void)invalidateTimer
{
[_timer invalidate];
_timer = nil;
}
- (void)setupPageControl
{
if (_pageControl) [_pageControl removeFromSuperview]; //
if (self.imagePathsGroup.count == 0 || self.onlyDisplayText) return;
if ((self.imagePathsGroup.count == 1) && self.hidesForSinglePage) return;
int indexOnPageControl = [self pageControlIndexWithCurrentCellIndex:[self currentIndex]];
switch (self.pageControlStyle) {
case SDCycleScrollViewPageContolStyleAnimated:
{
TAPageControl *pageControl = [[TAPageControl alloc] init];
pageControl.numberOfPages = self.imagePathsGroup.count;
pageControl.dotColor = self.currentPageDotColor;
pageControl.userInteractionEnabled = NO;
pageControl.currentPage = indexOnPageControl;
[self addSubview:pageControl];
_pageControl = pageControl;
}
break;
case SDCycleScrollViewPageContolStyleClassic:
{
UIPageControl *pageControl = [[UIPageControl alloc] init];
pageControl.numberOfPages = self.imagePathsGroup.count;
pageControl.currentPageIndicatorTintColor = self.currentPageDotColor;
pageControl.pageIndicatorTintColor = self.pageDotColor;
pageControl.userInteractionEnabled = NO;
pageControl.currentPage = indexOnPageControl;
[self addSubview:pageControl];
_pageControl = pageControl;
}
break;
default:
break;
}
// pagecontroldot
if (self.currentPageDotImage) {
self.currentPageDotImage = self.currentPageDotImage;
}
if (self.pageDotImage) {
self.pageDotImage = self.pageDotImage;
}
}
- (void)automaticScroll
{
if (0 == _totalItemsCount) return;
int currentIndex = [self currentIndex];
int targetIndex = currentIndex + 1;
[self scrollToIndex:targetIndex];
}
- (void)scrollToIndex:(int)targetIndex
{
if (targetIndex >= _totalItemsCount) {
if (self.infiniteLoop) {
targetIndex = _totalItemsCount * 0.5;
[_mainView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:targetIndex inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
}
return;
}
[_mainView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:targetIndex inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:YES];
}
- (int)currentIndex
{
if (_mainView.sd_width == 0 || _mainView.sd_height == 0) {
return 0;
}
int index = 0;
if (_flowLayout.scrollDirection == UICollectionViewScrollDirectionHorizontal) {
index = (_mainView.contentOffset.x + _flowLayout.itemSize.width * 0.5) / _flowLayout.itemSize.width;
} else {
index = (_mainView.contentOffset.y + _flowLayout.itemSize.height * 0.5) / _flowLayout.itemSize.height;
}
return MAX(0, index);
}
- (int)pageControlIndexWithCurrentCellIndex:(NSInteger)index
{
return (int)index % self.imagePathsGroup.count;
}
- (void)clearCache
{
[[self class] clearImagesCache];
}
+ (void)clearImagesCache
{
[[[SDWebImageManager sharedManager] imageCache] clearWithCacheType:SDImageCacheTypeDisk completion:nil];
}
#pragma mark - life circles
- (void)layoutSubviews
{
self.delegate = self.delegate;
[super layoutSubviews];
_flowLayout.itemSize = self.frame.size;
_mainView.frame = self.bounds;
if (_mainView.contentOffset.x == 0 && _totalItemsCount) {
int targetIndex = 0;
if (self.infiniteLoop) {
targetIndex = _totalItemsCount * 0.5;
}else{
targetIndex = 0;
}
[_mainView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:targetIndex inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
}
CGSize size = CGSizeZero;
if ([self.pageControl isKindOfClass:[TAPageControl class]]) {
TAPageControl *pageControl = (TAPageControl *)_pageControl;
if (!(self.pageDotImage && self.currentPageDotImage && CGSizeEqualToSize(kCycleScrollViewInitialPageControlDotSize, self.pageControlDotSize))) {
pageControl.dotSize = self.pageControlDotSize;
}
size = [pageControl sizeForNumberOfPages:self.imagePathsGroup.count];
} else {
size = CGSizeMake(self.imagePathsGroup.count * self.pageControlDotSize.width * 1.5, self.pageControlDotSize.height);
// ios14 pageControl size
if (@available(iOS 14.0, *)) {
if ([self.pageControl isKindOfClass:[UIPageControl class]]) {
UIPageControl *pageControl = (UIPageControl *)_pageControl;
size.width = [pageControl sizeForNumberOfPages:self.imagePathsGroup.count].width;
}
}
}
CGFloat x = (self.sd_width - size.width) * 0.5;
if (self.pageControlAliment == SDCycleScrollViewPageContolAlimentRight) {
x = self.mainView.sd_width - size.width - 10;
}
CGFloat y = self.mainView.sd_height - size.height - 10;
if ([self.pageControl isKindOfClass:[TAPageControl class]]) {
TAPageControl *pageControl = (TAPageControl *)_pageControl;
[pageControl sizeToFit];
}
CGRect pageControlFrame = CGRectMake(x, y, size.width, size.height);
pageControlFrame.origin.y -= self.pageControlBottomOffset;
pageControlFrame.origin.x -= self.pageControlRightOffset;
self.pageControl.frame = pageControlFrame;
self.pageControl.hidden = !_showPageControl;
if (self.backgroundImageView) {
self.backgroundImageView.frame = self.bounds;
}
}
//ViewTimer
- (void)willMoveToSuperview:(UIView *)newSuperview
{
if (!newSuperview) {
[self invalidateTimer];
}
}
//timer scrollViewDidScroll访
- (void)dealloc {
_mainView.delegate = nil;
_mainView.dataSource = nil;
}
#pragma mark - public actions
- (void)adjustWhenControllerViewWillAppera
{
long targetIndex = [self currentIndex];
if (targetIndex < _totalItemsCount) {
[_mainView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:targetIndex inSection:0] atScrollPosition:UICollectionViewScrollPositionNone animated:NO];
}
}
#pragma mark - UICollectionViewDataSource
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return _totalItemsCount;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
SDCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:ID forIndexPath:indexPath];
long itemIndex = [self pageControlIndexWithCurrentCellIndex:indexPath.item];
if ([self.delegate respondsToSelector:@selector(setupCustomCell:forIndex:cycleScrollView:)] &&
[self.delegate respondsToSelector:@selector(customCollectionViewCellClassForCycleScrollView:)] && [self.delegate customCollectionViewCellClassForCycleScrollView:self]) {
[self.delegate setupCustomCell:cell forIndex:itemIndex cycleScrollView:self];
return cell;
}else if ([self.delegate respondsToSelector:@selector(setupCustomCell:forIndex:cycleScrollView:)] &&
[self.delegate respondsToSelector:@selector(customCollectionViewCellNibForCycleScrollView:)] && [self.delegate customCollectionViewCellNibForCycleScrollView:self]) {
[self.delegate setupCustomCell:cell forIndex:itemIndex cycleScrollView:self];
return cell;
}
NSString *imagePath = self.imagePathsGroup[itemIndex];
if (!self.onlyDisplayText && [imagePath isKindOfClass:[NSString class]]) {
if ([imagePath hasPrefix:@"http"]) {
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:imagePath] placeholderImage:self.placeholderImage];
} else {
UIImage *image = [UIImage imageNamed:imagePath];
if (!image) {
image = [UIImage imageWithContentsOfFile:imagePath];
}
cell.imageView.image = image;
}
} else if (!self.onlyDisplayText && [imagePath isKindOfClass:[UIImage class]]) {
cell.imageView.image = (UIImage *)imagePath;
}
if (_titlesGroup.count && itemIndex < _titlesGroup.count) {
cell.title = _titlesGroup[itemIndex];
}
if (!cell.hasConfigured) {
cell.titleLabelBackgroundColor = self.titleLabelBackgroundColor;
cell.titleLabelHeight = self.titleLabelHeight;
cell.titleLabelTextAlignment = self.titleLabelTextAlignment;
cell.titleLabelTextColor = self.titleLabelTextColor;
cell.titleLabelTextFont = self.titleLabelTextFont;
cell.hasConfigured = YES;
cell.imageView.contentMode = self.bannerImageViewContentMode;
cell.clipsToBounds = YES;
cell.onlyDisplayText = self.onlyDisplayText;
}
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
if ([self.delegate respondsToSelector:@selector(cycleScrollView:didSelectItemAtIndex:)]) {
[self.delegate cycleScrollView:self didSelectItemAtIndex:[self pageControlIndexWithCurrentCellIndex:indexPath.item]];
}
if (self.clickItemOperationBlock) {
self.clickItemOperationBlock([self pageControlIndexWithCurrentCellIndex:indexPath.item]);
}
}
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if (!self.imagePathsGroup.count) return; // timer
int itemIndex = [self currentIndex];
int indexOnPageControl = [self pageControlIndexWithCurrentCellIndex:itemIndex];
if ([self.pageControl isKindOfClass:[TAPageControl class]]) {
TAPageControl *pageControl = (TAPageControl *)_pageControl;
pageControl.currentPage = indexOnPageControl;
} else {
UIPageControl *pageControl = (UIPageControl *)_pageControl;
pageControl.currentPage = indexOnPageControl;
}
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
if (self.autoScroll) {
[self invalidateTimer];
}
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
if (self.autoScroll) {
[self setupTimer];
}
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
[self scrollViewDidEndScrollingAnimation:self.mainView];
}
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
if (!self.imagePathsGroup.count) return; // timer
int itemIndex = [self currentIndex];
int indexOnPageControl = [self pageControlIndexWithCurrentCellIndex:itemIndex];
if ([self.delegate respondsToSelector:@selector(cycleScrollView:didScrollToIndex:)]) {
[self.delegate cycleScrollView:self didScrollToIndex:indexOnPageControl];
} else if (self.itemDidScrollOperationBlock) {
self.itemDidScrollOperationBlock(indexOnPageControl);
}
}
- (void)makeScrollViewScrollToIndex:(NSInteger)index{
if (self.autoScroll) {
[self invalidateTimer];
}
if (0 == _totalItemsCount) return;
[self scrollToIndex:(int)(_totalItemsCount * 0.5 + index)];
if (self.autoScroll) {
[self setupTimer];
}
}
@end

View File

@@ -0,0 +1,44 @@
//
// UIView+SDExtension.h
// SDRefreshView
//
// Created by aier on 15-2-23.
// Copyright (c) 2015年 GSD. All rights reserved.
//
/*
*********************************************************************************
*
* 🌟🌟🌟 新建SDCycleScrollView交流QQ群185534916 🌟🌟🌟
*
* 在您使用此自动轮播库的过程中如果出现bug请及时以以下任意一种方式联系我们我们会及时修复bug并
* 帮您解决问题。
* 新浪微博:GSD_iOS
* Email : gsdios@126.com
* GitHub: https://github.com/gsdios
*
* 另我的自动布局库SDAutoLayout
* 一行代码搞定自动布局支持Cell和Tableview高度自适应Label和ScrollView内容自适应致力于
* 做最简单易用的AutoLayout库。
* 视频教程http://www.letv.com/ptv/vplay/24038772.html
* 用法示例https://github.com/gsdios/SDAutoLayout/blob/master/README.md
* GitHubhttps://github.com/gsdios/SDAutoLayout
*********************************************************************************
*/
#import <UIKit/UIKit.h>
#define SDColorCreater(r, g, b, a) [UIColor colorWithRed:(r / 255.0) green:(g / 255.0) blue:(b / 255.0) alpha:a]
@interface UIView (SDExtension)
@property (nonatomic, assign) CGFloat sd_height;
@property (nonatomic, assign) CGFloat sd_width;
@property (nonatomic, assign) CGFloat sd_y;
@property (nonatomic, assign) CGFloat sd_x;
@end

View File

@@ -0,0 +1,107 @@
//
// UIView+SDExtension.m
// SDRefreshView
//
// Created by aier on 15-2-23.
// Copyright (c) 2015 GSD. All rights reserved.
//
/*
*********************************************************************************
*
* 🌟🌟🌟 SDCycleScrollViewQQ185534916 🌟🌟🌟
*
* 使bugbug
*
* :GSD_iOS
* Email : gsdios@126.com
* GitHub: https://github.com/gsdios
*
* SDAutoLayout
* CellTableviewLabelScrollView
* AutoLayout
* http://www.letv.com/ptv/vplay/24038772.html
* https://github.com/gsdios/SDAutoLayout/blob/master/README.md
* GitHubhttps://github.com/gsdios/SDAutoLayout
*********************************************************************************
*/
/*
*********************************************************************************
*
* 使bugbug
*
* :GSD_iOS
* Email : gsdios@126.com
* GitHub: https://github.com/gsdios
*
* SDAutoLayout
* CellTableviewLabelScrollView
* AutoLayout
* http://www.letv.com/ptv/vplay/24038772.html
* https://github.com/gsdios/SDAutoLayout/blob/master/README.md
* GitHubhttps://github.com/gsdios/SDAutoLayout
*********************************************************************************
*/
#import "UIView+SDExtension.h"
@implementation UIView (SDExtension)
- (CGFloat)sd_height
{
return self.frame.size.height;
}
- (void)setSd_height:(CGFloat)sd_height
{
CGRect temp = self.frame;
temp.size.height = sd_height;
self.frame = temp;
}
- (CGFloat)sd_width
{
return self.frame.size.width;
}
- (void)setSd_width:(CGFloat)sd_width
{
CGRect temp = self.frame;
temp.size.width = sd_width;
self.frame = temp;
}
- (CGFloat)sd_y
{
return self.frame.origin.y;
}
- (void)setSd_y:(CGFloat)sd_y
{
CGRect temp = self.frame;
temp.origin.y = sd_y;
self.frame = temp;
}
- (CGFloat)sd_x
{
return self.frame.origin.x;
}
- (void)setSd_x:(CGFloat)sd_x
{
CGRect temp = self.frame;
temp.origin.x = sd_x;
self.frame = temp;
}
@end