iOS 跑马灯封装(带点击事件)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/walkerwqp/article/details/80007642

1.WAdvertScrollView.h

#import <UIKit/UIKit.h>


@class WAdvertScrollView;


typedef enum : NSUInteger {

    /// 一行文字滚动样式

    WAdvertScrollViewStyleNormal,

    /// 二行文字滚动样式

    WAdvertScrollViewStyleMore,

扫描二维码关注公众号,回复: 3177434 查看本文章

} WAdvertScrollViewStyle;


@protocol WAdvertScrollViewDelegate <NSObject>


/// delegate 方法

- (void)advertScrollView:(WAdvertScrollView *)advertScrollView didSelectedItemAtIndex:(NSInteger)index;


@end


@interface WAdvertScrollView : UIView


#pragma mark - - - 公共 API

/** delegate */

@property (nonatomic, weak) id<WAdvertScrollViewDelegate> delegate;

/** 默认 SGAdvertScrollViewStyleNormal 样式 */

@property (nonatomic, assign) WAdvertScrollViewStyle advertScrollViewStyle;

/** 滚动时间间隔,默认为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 = [UIFont systemFontOfSize: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 = [UIFont systemFontOfSize: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 = [UIFont systemFontOfSize:advertScrollViewTitleFont];

    }

    return _bottomLabel;

}

@end



#pragma mark - - - WAdvertScrollView

@interface WAdvertScrollView () <UICollectionViewDelegate, UICollectionViewDataSource>

@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:[WAdvertScrollViewNormalCell class] 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:[NSIndexPath indexPathForItem: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:advertScrollViewMoreCell forIndexPath: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:[NSURL URLWithString:@"www.kingsic22.com"]];

                    

                } else {

                    cell.topSignImageView.image = [UIImage imageNamed:@"kingsic"];

                }

            } else {

                if ([topImagePath hasPrefix:@"http"]) {

                    [cell.topSignImageView sd_setImageWithURL:[NSURL URLWithString:topImagePath]];

                    

                } else {

                    cell.topSignImageView.image = [UIImage imageNamed: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:[NSURL URLWithString:@"www.kingsic22.com"]];

                    

                } else {

                    cell.bottomSignImageView.image = [UIImage imageNamed:@"kingsic"];

                }

            } else {

                if ([bottomImagePath hasPrefix:@"http"]) {

                    [cell.bottomSignImageView sd_setImageWithURL:[NSURL URLWithString:bottomImagePath]];

                    

                } else {

                    cell.bottomSignImageView.image = [UIImage imageNamed: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:advertScrollViewNormalCell forIndexPath: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:[NSURL URLWithString:@"www.kingsic22.com"]];

                    

                } else {

                    cell.signImageView.image = [UIImage imageNamed:@"kingsic"];

                }

            } else {

                if ([imagePath hasPrefix:@"http"]) {

                    [cell.signImageView sd_setImageWithURL:[NSURL URLWithString:imagePath]];

                    

                } else {

                    cell.signImageView.image = [UIImage imageNamed: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.delegate respondsToSelector:@selector(advertScrollView:didSelectedItemAtIndex:)]) {

        [self.delegate advertScrollView:self didSelectedItemAtIndex:indexPath.item];

    }

}


#pragma mark - - - NSTimer

- (void)addTimer {

    [self removeTimer];

    

    self.timer = [NSTimer timerWithTimeInterval:self.scrollTimeInterval target:self selector:@selector(beginUpdateUI) userInfo:nil repeats:YES];

    [[NSRunLoop mainRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];

}


- (void)removeTimer {

    [_timer invalidate];

    _timer = nil;

}


- (void)beginUpdateUI {

    if (self.titleArr.count == 0) return;

    

    // 1、当前正在展示的位置

    NSIndexPath *currentIndexPath = [[self.collectionView indexPathsForVisibleItems] lastObject];

    

    // 马上显示回最中间那组的数据

    NSIndexPath *resetCurrentIndexPath = [NSIndexPath indexPathForItem: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(@"点击跑马灯");

}



猜你喜欢

转载自blog.csdn.net/walkerwqp/article/details/80007642