1.WAdvertScrollView.h
#import
@class WAdvertScrollView;
typedef enum : NSUInteger {
/// 一行文字滚动样式
WAdvertScrollViewStyleNormal,
/// 二行文字滚动样式
WAdvertScrollViewStyleMore,
} WAdvertScrollViewStyle;
@protocol WAdvertScrollViewDelegate
/// delegate 方法
- (void)advertScrollView:(WAdvertScrollView *)advertScrollView didSelectedItemAtIndex:(NSInteger)index;
@end
@interface WAdvertScrollView : UIView
#pragma mark - - - 公共 API
/** delegate */
@property (nonatomic, weak) id delegate;
/** 默认 SGAdvertScrollViewStyleNormal 样式 */
@property (nonatomic, assign) WAdvertScrollViewStyleadvertScrollViewStyle;
/** 滚动时间间隔,默认为3s */
@property (nonatomic, assign) CFTimeInterval scrollTimeInterval;
/** 标题字体字号,默认为13号字体 */
@property (nonatomic, strong) UIFont *titleFont;
#pragma mark - - - WAdvertScrollViewStyleNormal 样式下的 API
/** 左边标志图片数组 */
@property (nonatomic, strong) NSArray *signImages;
/** 标题数组 */
@property (nonatomic, strong) NSArray *titles;
/** 标题字体颜色,默认为黑色 */
@property (nonatomic, strong) UIColor *titleColor;
/** 标题文字位置,默认为 NSTextAlignmentLeft,仅仅针对标题起作用 */
@property (nonatomic, assign) NSTextAlignment textAlignment;
#pragma mark - - - WAdvertScrollViewStyleMore 样式下的 API
/** 顶部左边标志图片数组 */
@property (nonatomic, strong) NSArray *topSignImages;
/** 顶部标题数组 */
@property (nonatomic, strong) NSArray *topTitles;
/** 底部左边标志图片数组 */
@property (nonatomic, strong) NSArray *bottomSignImages;
/** 底部标题数组 */
@property (nonatomic, strong) NSArray *bottomTitles;
/** 顶部标题字体颜色,默认为黑色 */
@property (nonatomic, strong) UIColor *topTitleColor;
/** 底部标题字体颜色,默认为黑色 */
@property (nonatomic, strong) UIColor *bottomTitleColor;
@end
2.WAdvertScrollView.m
#import "WAdvertScrollView.h"
#import "UIImageView+WebCache.h"
static NSInteger const advertScrollViewTitleFont = 13;
#pragma mark - - - WAdvertScrollViewStyleNormal 样式下的 cell
@interface WAdvertScrollViewNormalCell : UICollectionViewCell
@property (nonatomic, strong) UIImageView *signImageView;
@property (nonatomic, strong) UILabel *titleLabel;
@end
@implementation WAdvertScrollViewNormalCell
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.backgroundColor = [UIColor clearColor];
[self.contentView addSubview:self.signImageView];
[self.contentView addSubview:self.titleLabel];
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
CGFloat spacing = 5;
CGFloat signImageViewW = self.signImageView.image.size.width;
CGFloat signImageViewH = self.signImageView.image.size.height;
CGFloat signImageViewX = 0;
CGFloat signImageViewY = 0;
self.signImageView.frame = CGRectMake(signImageViewX, signImageViewY, signImageViewW, signImageViewH);
CGFloat labelX = 0;
if (self.signImageView.image == nil) {
labelX = 0;
} else {
labelX = CGRectGetMaxX(self.signImageView.frame) + 0.5 * spacing;
}
CGFloat labelY = 0;
CGFloat labelW = self.frame.size.width - labelX;
CGFloat labelH = self.frame.size.height;
self.titleLabel.frame = CGRectMake(labelX, labelY, labelW, labelH);
CGPoint topPoint = self.signImageView.center;
topPoint.y = _titleLabel.center.y;
_signImageView.center = topPoint;
}
- (UIImageView *)signImageView {
if (!_signImageView) {
_signImageView = [[UIImageView alloc] init];
}
return _signImageView;
}
- (UILabel *)titleLabel {
if (!_titleLabel) {
_titleLabel = [[UILabel alloc] init];
_titleLabel.textColor = [UIColor blackColor];
_titleLabel.font = [UIFontsystemFontOfSize:advertScrollViewTitleFont];
}
return _titleLabel;
}
@end
#pragma mark - - - WAdvertScrollViewStyleMore 样式下的 cell
@interface WAdvertScrollViewMoreCell : UICollectionViewCell
@property (nonatomic, strong) UIImageView *topSignImageView;
@property (nonatomic, strong) UILabel *topLabel;
@property (nonatomic, strong) UIImageView *bottomSignImageView;
@property (nonatomic, strong) UILabel *bottomLabel;
@end
@implementation WAdvertScrollViewMoreCell
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.backgroundColor = [UIColor clearColor];
[self.contentView addSubview:self.topSignImageView];
[self.contentView addSubview:self.topLabel];
[self.contentView addSubview:self.bottomSignImageView];
[self.contentView addSubview:self.bottomLabel];
}
return self;
}
- (void)layoutSubviews {
[super layoutSubviews];
CGFloat spacing = 5;
CGFloat topSignImageViewW = self.topSignImageView.image.size.width;
CGFloat topSignImageViewH = self.topSignImageView.image.size.height;
CGFloat topSignImageViewX = 0;
CGFloat topSignImageViewY = spacing;
self.topSignImageView.frame = CGRectMake(topSignImageViewX, topSignImageViewY, topSignImageViewW, topSignImageViewH);
CGFloat topLabelX = 0;
if (self.topSignImageView.image == nil) {
topLabelX = 0;
} else {
topLabelX = CGRectGetMaxX(self.topSignImageView.frame) + 0.5 * spacing;
}
CGFloat topLabelY = topSignImageViewY;
CGFloat topLabelW = self.frame.size.width - topLabelX;
CGFloat topLabelH = 0.5 * (self.frame.size.height - 2 * topLabelY);
self.topLabel.frame = CGRectMake(topLabelX, topLabelY, topLabelW, topLabelH);
CGPoint topPoint = self.topSignImageView.center;
topPoint.y = _topLabel.center.y;
_topSignImageView.center = topPoint;
CGFloat bottomSignImageViewW = self.bottomSignImageView.image.size.width;
CGFloat bottomSignImageViewH = self.bottomSignImageView.image.size.height;
CGFloat bottomSignImageViewX = 0;
CGFloat bottomSignImageViewY = CGRectGetMaxY(self.topLabel.frame);
self.bottomSignImageView.frame = CGRectMake(bottomSignImageViewX, bottomSignImageViewY, bottomSignImageViewW, bottomSignImageViewH);
CGFloat bottomLabelX = 0;
if (self.bottomSignImageView.image == nil) {
bottomLabelX = 0;
} else {
bottomLabelX = CGRectGetMaxX(self.bottomSignImageView.frame) + 0.5 * spacing;
}
CGFloat bottomLabelY = CGRectGetMaxY(self.topLabel.frame);
CGFloat bottomLabelW = self.frame.size.width - bottomLabelX;
CGFloat bottomLabelH = topLabelH;
self.bottomLabel.frame = CGRectMake(bottomLabelX, bottomLabelY, bottomLabelW, bottomLabelH);
CGPoint bottomPoint = self.bottomSignImageView.center;
bottomPoint.y = _bottomLabel.center.y;
_bottomSignImageView.center = bottomPoint;
}
- (UIImageView *)topSignImageView {
if (!_topSignImageView) {
_topSignImageView = [[UIImageView alloc] init];
}
return _topSignImageView;
}
- (UILabel *)topLabel {
if (!_topLabel) {
_topLabel = [[UILabel alloc] init];
_topLabel.textColor = [UIColor blackColor];
_topLabel.font = [UIFontsystemFontOfSize:advertScrollViewTitleFont];
}
return _topLabel;
}
- (UIImageView *)bottomSignImageView {
if (!_bottomSignImageView) {
_bottomSignImageView = [[UIImageView alloc] init];
}
return _bottomSignImageView;
}
- (UILabel *)bottomLabel {
if (!_bottomLabel) {
_bottomLabel = [[UILabel alloc] init];
_bottomLabel.textColor = [UIColor blackColor];
_bottomLabel.font = [UIFontsystemFontOfSize:advertScrollViewTitleFont];
}
return _bottomLabel;
}
@end
#pragma mark - - - WAdvertScrollView
@interface WAdvertScrollView ()
@property (nonatomic, strong) UICollectionViewFlowLayout *flowLayout;
@property (nonatomic, strong) UICollectionView *collectionView;
@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, strong) NSArray *titleArr;
@property (nonatomic, strong) NSArray *imageArr;
@property (nonatomic, strong) NSArray *bottomImageArr;
@property (nonatomic, strong) NSArray *bottomTitleArr;
@end
@implementation WAdvertScrollView
static NSInteger const advertScrollViewMaxSections = 100;
static NSString *const advertScrollViewNormalCell = @"advertScrollViewNormalCell";
static NSString *const advertScrollViewMoreCell = @"advertScrollViewMoreCell";
- (void)awakeFromNib {
[super awakeFromNib];
[self initialization];
[self setupSubviews];
}
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
self.backgroundColor = [UIColor whiteColor];
[self initialization];
[self setupSubviews];
}
return self;
}
- (void)willMoveToSuperview:(UIView *)newSuperview {
if (!newSuperview) {
[self removeTimer];
}
}
- (void)dealloc {
_collectionView.delegate = nil;
_collectionView.dataSource = nil;
}
- (void)initialization {
_scrollTimeInterval = 3.0;
[self addTimer];
_advertScrollViewStyle = WAdvertScrollViewStyleNormal;
}
- (void)setupSubviews {
UIView *tempView = [[UIView alloc] initWithFrame:CGRectZero];
[self addSubview:tempView];
[self addSubview:self.collectionView];
}
- (UICollectionView *)collectionView {
if (!_collectionView) {
_flowLayout = [[UICollectionViewFlowLayout alloc] init];
_flowLayout.minimumLineSpacing = 0;
_collectionView = [[UICollectionView alloc] initWithFrame:self.bounds collectionViewLayout:_flowLayout];
_collectionView.delegate = self;
_collectionView.dataSource = self;
_collectionView.scrollsToTop = NO;
_collectionView.scrollEnabled = NO;
_collectionView.pagingEnabled = YES;
_collectionView.showsVerticalScrollIndicator = NO;
_collectionView.backgroundColor = [UIColor clearColor];
[_collectionView registerClass:[WAdvertScrollViewNormalCellclass] forCellWithReuseIdentifier:advertScrollViewNormalCell];
}
return _collectionView;
}
- (void)layoutSubviews {
[super layoutSubviews];
_flowLayout.itemSize = CGSizeMake(self.frame.size.width, self.frame.size.height);
_collectionView.frame = self.bounds;
if (self.titleArr.count > 1) {
[self defaultSelectedScetion];
}
}
- (void)defaultSelectedScetion {
[self.collectionView scrollToItemAtIndexPath:[NSIndexPathindexPathForItem:0 inSection:0.5 * advertScrollViewMaxSections] atScrollPosition:UICollectionViewScrollPositionBottom animated:NO];
}
#pragma mark - - - UICollectionView 的 dataSource、delegate方法
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView*)collectionView {
return advertScrollViewMaxSections;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return self.titleArr.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView*)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
if (self.advertScrollViewStyle == WAdvertScrollViewStyleMore) {
WAdvertScrollViewMoreCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:advertScrollViewMoreCellforIndexPath:indexPath];
NSInteger topImagesCount = self.imageArr.count;
if (topImagesCount > 0) {
NSString *topImagePath = self.imageArr[indexPath.item];
if (topImagePath == nil || [topImagePath isEqualToString:@""]) { // 解决 iOS 11 无图片,控制台打印问题
if ([topImagePath hasPrefix:@"http"]) {
[cell.topSignImageView sd_setImageWithURL:[NSURLURLWithString:@"www.kingsic22.com"]];
} else {
cell.topSignImageView.image = [UIImageimageNamed:@"kingsic"];
}
} else {
if ([topImagePath hasPrefix:@"http"]) {
[cell.topSignImageView sd_setImageWithURL:[NSURLURLWithString:topImagePath]];
} else {
cell.topSignImageView.image = [UIImageimageNamed:topImagePath];
}
}
}
cell.topLabel.text = self.titleArr[indexPath.item];
NSInteger bottomImagesCount = self.bottomImageArr.count;
if (bottomImagesCount > 0) {
NSString *bottomImagePath = self.bottomImageArr[indexPath.item];
if (bottomImagePath == nil || [bottomImagePath isEqualToString:@""]) { // 解决 iOS 11 无图片,控制台打印问题
if ([bottomImagePath hasPrefix:@"http"]) {
[cell.bottomSignImageView sd_setImageWithURL:[NSURLURLWithString:@"www.kingsic22.com"]];
} else {
cell.bottomSignImageView.image = [UIImageimageNamed:@"kingsic"];
}
} else {
if ([bottomImagePath hasPrefix:@"http"]) {
[cell.bottomSignImageView sd_setImageWithURL:[NSURLURLWithString:bottomImagePath]];
} else {
cell.bottomSignImageView.image = [UIImageimageNamed:bottomImagePath];
}
}
}
cell.bottomLabel.text = self.bottomTitleArr[indexPath.item];
if (self.titleFont) {
cell.topLabel.font = self.titleFont;
cell.bottomLabel.font = self.titleFont;
}
if (self.topTitleColor) {
cell.topLabel.textColor = self.topTitleColor;
}
if (self.bottomTitleColor) {
cell.bottomLabel.textColor = self.bottomTitleColor;
}
return cell;
} else {
WAdvertScrollViewNormalCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:advertScrollViewNormalCellforIndexPath:indexPath];
NSInteger imagesCount = self.imageArr.count;
if (imagesCount > 0) {
NSString *imagePath = self.imageArr[indexPath.item];
if (imagePath == nil || [imagePath isEqualToString:@""]) { // 解决 iOS 11 无图片,控制台打印问题
if ([imagePath hasPrefix:@"http"]) {
[cell.signImageView sd_setImageWithURL:[NSURLURLWithString:@"www.kingsic22.com"]];
} else {
cell.signImageView.image = [UIImageimageNamed:@"kingsic"];
}
} else {
if ([imagePath hasPrefix:@"http"]) {
[cell.signImageView sd_setImageWithURL:[NSURLURLWithString:imagePath]];
} else {
cell.signImageView.image = [UIImageimageNamed:imagePath];
}
}
}
cell.titleLabel.text = self.titleArr[indexPath.item];
if (self.textAlignment) {
cell.titleLabel.textAlignment = self.textAlignment;
}
if (self.titleFont) {
cell.titleLabel.font = self.titleFont;
}
if (self.titleColor) {
cell.titleLabel.textColor = self.titleColor;
}
return cell;
}
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
if (self.delegate && [self.delegaterespondsToSelector:@selector(advertScrollView:didSelectedItemAtIndex:)]) {
[self.delegate advertScrollView:selfdidSelectedItemAtIndex:indexPath.item];
}
}
#pragma mark - - - NSTimer
- (void)addTimer {
[self removeTimer];
self.timer = [NSTimer timerWithTimeInterval:self.scrollTimeIntervaltarget:self selector:@selector(beginUpdateUI) userInfo:nil repeats:YES];
[[NSRunLoop mainRunLoop] addTimer:_timerforMode:NSRunLoopCommonModes];
}
- (void)removeTimer {
[_timer invalidate];
_timer = nil;
}
- (void)beginUpdateUI {
if (self.titleArr.count == 0) return;
// 1、当前正在展示的位置
NSIndexPath *currentIndexPath = [[self.collectionViewindexPathsForVisibleItems] lastObject];
// 马上显示回最中间那组的数据
NSIndexPath *resetCurrentIndexPath = [NSIndexPathindexPathForItem:currentIndexPath.item inSection:0.5 * advertScrollViewMaxSections];
[self.collectionView scrollToItemAtIndexPath:resetCurrentIndexPath atScrollPosition:UICollectionViewScrollPositionBottom animated:NO];
// 2、计算出下一个需要展示的位置
NSInteger nextItem = resetCurrentIndexPath.item + 1;
NSInteger nextSection = resetCurrentIndexPath.section;
if (nextItem == self.titleArr.count) {
nextItem = 0;
nextSection++;
}
NSIndexPath *nextIndexPath = [NSIndexPath indexPathForItem:nextItem inSection:nextSection];
// 3、通过动画滚动到下一个位置
[self.collectionView scrollToItemAtIndexPath:nextIndexPath atScrollPosition:UICollectionViewScrollPositionBottom animated:YES];
}
#pragma mark - - - setting
- (void)setAdvertScrollViewStyle:(WAdvertScrollViewStyle)advertScrollViewStyle {
_advertScrollViewStyle = advertScrollViewStyle;
if (advertScrollViewStyle == WAdvertScrollViewStyleMore) {
_advertScrollViewStyle = WAdvertScrollViewStyleMore;
[_collectionView registerClass:[WAdvertScrollViewMoreCell class] forCellWithReuseIdentifier:advertScrollViewMoreCell];
}
}
- (void)setSignImages:(NSArray *)signImages {
_signImages = signImages;
if (signImages) {
self.imageArr = [NSArray arrayWithArray:signImages];
}
}
- (void)setTitles:(NSArray *)titles {
_titles = titles;
if (titles.count > 1) {
[self addTimer];
} else {
[self removeTimer];
}
self.titleArr = [NSArray arrayWithArray:titles];
[self.collectionView reloadData];
}
- (void)setTitleFont:(UIFont *)titleFont {
_titleFont = titleFont;
}
- (void)setTextAlignment:(NSTextAlignment)textAlignment {
_textAlignment = textAlignment;
}
- (void)setTopSignImages:(NSArray *)topSignImages {
_topSignImages = topSignImages;
if (topSignImages) {
self.imageArr = [NSArray arrayWithArray:topSignImages];
}
}
- (void)setTopTitles:(NSArray *)topTitles {
_topTitles = topTitles;
if (topTitles.count > 1) {
[self addTimer];
} else {
[self removeTimer];
}
self.titleArr = [NSArray arrayWithArray:topTitles];
[self.collectionView reloadData];
}
- (void)setBottomSignImages:(NSArray *)bottomSignImages {
_bottomSignImages = bottomSignImages;
if (bottomSignImages) {
self.bottomImageArr = [NSArray arrayWithArray:bottomSignImages];
}
}
- (void)setBottomTitles:(NSArray *)bottomTitles {
_bottomTitles = bottomTitles;
if (bottomTitles) {
self.bottomTitleArr = [NSArray arrayWithArray:bottomTitles];
}
}
- (void)setScrollTimeInterval:(CFTimeInterval)scrollTimeInterval {
_scrollTimeInterval = scrollTimeInterval;
if (scrollTimeInterval) {
[self addTimer];
}
}
@end
3.调用
切记 遵循代理WAdvertScrollViewDelegate
self.titleScrollView = [[WAdvertScrollView alloc] initWithFrame:CGRectMake(imagView.frame.size.width + 10, 0, self.titleView.frame.size.width - (imagView.frame.size.width + 20), 40)];
self.titleScrollView.advertScrollViewStyle = WAdvertScrollViewStyleMore;
self.titleScrollView.titleColor = [[UIColor blackColor] colorWithAlphaComponent:0.7];
self.titleScrollView.scrollTimeInterval = 5;
self.titleScrollView.titles = @[@"", @"", @""];
self.titleScrollView.titleFont = [UIFont systemFontOfSize:14];
self.titleScrollView.delegate = self;
self.titleScrollView.layer.cornerRadius = 20;
self.titleScrollView.layer.masksToBounds = YES;
self.titleScrollView.backgroundColor = [UIColor whiteColor];
[self.titleView addSubview:self.titleScrollView];
4.代理方法
/// 代理方法
- (void)advertScrollView:(WAdvertScrollView *)advertScrollView didSelectedItemAtIndex:(NSInteger)index {
NSLog(@"点击跑马灯");
}