声明文件
@class Jie_CarouselNewsView;
@protocol Jie_CarouselNewsDataSource <NSObject>
@required
// 需要显示轮播的数据, 显示普通的字符串
- (NSArray<NSString *> *)carouseNewsData:(Jie_CarouselNewsView *)jie_carouseNewView;
@optional
// 修改最大显示的行数, 默认显示一行
- (NSInteger)maxShowedRow:(Jie_CarouselNewsView *)jie_carouseNewView;
// 需要显示轮播的数据, 显示属性字符串
- (NSArray<NSAttributedString *> *)carouseNewsAttributedData:(Jie_CarouselNewsView *)jie_carouseNewView;
// 默认0.05s
- (NSTimeInterval)carouseNewsTimeInterval:(Jie_CarouselNewsView *)jie_carouseNewView;
// 是否翻页滚动, 默认不按页滚动,
- (BOOL)carousenewsScrollPageingEnable:(Jie_CarouselNewsView *)jie_carouseNewView;
@end
@protocol Jie_CarouselNewsViewDelegate <NSObject>
- (void)selectedRowAtIndex:(NSInteger)index jie_carouseNewView:(Jie_CarouselNewsView *)jie_carouseNewView;
@end
@interface Jie_CarouselNewsView : UIView
@property(nonatomic, weak)id<Jie_CarouselNewsDataSource> dataSource;
@property(nonatomic, weak)id<Jie_CarouselNewsViewDelegate> delegate;
@end
定义文件
#import "Jie_CarouselNewsView.h"
@interface Jie_CarouselNewsView ()
@property(nonatomic, weak)NSTimer *timer;
@property(nonatomic, strong)NSArray *dataArray;
@property(nonatomic, strong)NSArray *attributedDataArray;
@property(nonatomic, assign)NSInteger showedRow;
@property(nonatomic, assign)NSTimeInterval timeInterval;
@property(nonatomic, assign)BOOL pageingEnable;
@property(nonatomic, strong)NSMutableArray<UILabel *> *labelArray;
@property(nonatomic, assign)NSInteger lastIndex;
@end
static NSInteger defaultShowedRow = 1;
static NSTimeInterval defaultTimeInterval = 0.05;
static BOOL defaultPageingEnable = NO;
@implementation Jie_CarouselNewsView
- (instancetype)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
self.clipsToBounds = YES;
}
return self;
}
- (void)layoutSubviews {
[self addLabels];
[self.timer fire];
}
- (void)addLabels {
CGFloat labelH = self.frame.size.height / _showedRow;
CGFloat labelW = self.frame.size.width;
for (int i = 0; i < _showedRow; i++) {
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, labelH * i, labelW, labelH)];
label.tag = i;
label.userInteractionEnabled = YES;
if (_dataArray.count != 0) {
label.text = _dataArray[i];
}
if (_attributedDataArray.count != 0) {
label.attributedText = _attributedDataArray[i];
}
[self addSubview:label];
[self.labelArray addObject:label];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
[label addGestureRecognizer:tap];
}
if (_dataArray.count > _showedRow || _attributedDataArray.count > _showedRow) {
UILabel *lastLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, labelH * _showedRow, labelW, labelH)];
lastLabel.userInteractionEnabled = YES;
if (_dataArray.count != 0) {
lastLabel.text = _dataArray[_showedRow];
}
if (_attributedDataArray.count != 0) {
lastLabel.attributedText = _attributedDataArray[_showedRow];
}
[self addSubview:lastLabel];
[self.labelArray addObject:lastLabel];
_lastIndex = _showedRow;
lastLabel.tag = _showedRow;
UITapGestureRecognizer *last_tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
[lastLabel addGestureRecognizer:last_tap];
}
}
- (void)setDataSource:(id<Jie_CarouselNewsDataSource>)dataSource {
_dataSource = dataSource;
if ([_dataSource respondsToSelector:@selector(maxShowedRow:)]) {
_showedRow = [_dataSource maxShowedRow:self];
} else {
_showedRow = defaultShowedRow;
}
if ([_dataSource respondsToSelector:@selector(carouseNewsData:)]) {
_dataArray = [_dataSource carouseNewsData:self];
}
if ([_dataSource respondsToSelector:@selector(carouseNewsAttributedData:)]) {
_attributedDataArray = [_dataSource carouseNewsAttributedData:self];
}
if ([_dataSource respondsToSelector:@selector(carouseNewsTimeInterval:)]) {
_timeInterval = [_dataSource carouseNewsTimeInterval:self];
} else {
_timeInterval = defaultTimeInterval;
}
if ([_dataSource respondsToSelector:@selector(carousenewsScrollPageingEnable:)]) {
_pageingEnable = [_dataSource carousenewsScrollPageingEnable:self];
} else {
_pageingEnable = defaultPageingEnable;
}
}
- (NSMutableArray<UILabel *> *)labelArray {
if (!_labelArray) {
_labelArray = [[NSMutableArray alloc] init];
}
return _labelArray;
}
- (NSTimer *)timer {
if (!_timer) {
_timer = [NSTimer scheduledTimerWithTimeInterval:_timeInterval target:self selector:@selector(changLabelFrame) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:_timer forMode:NSRunLoopCommonModes];
}
return _timer;
}
- (void)changLabelFrame {
[self.labelArray enumerateObjectsUsingBlock:^(UILabel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
if (obj.frame.origin.y <= -(self.frame.size.height / self.showedRow)) {
obj.frame = CGRectMake(0, self.frame.size.height, self.frame.size.width, self.frame.size.height / self.showedRow);
self.lastIndex++;
if (self.lastIndex == self.dataArray.count) {
self.lastIndex = 0;
}
obj.tag = self.lastIndex;
if (self.dataArray.count != 0) {
obj.text = self.dataArray[self.lastIndex];
}
if (self.attributedDataArray.count != 0) {
obj.attributedText = self.attributedDataArray[self.lastIndex];
}
} else {
CGRect rect = obj.frame;
if (self.pageingEnable) {
[UIView animateWithDuration:0.5 animations:^{
obj.frame = CGRectMake(rect.origin.x, rect.origin.y - rect.size.height, rect.size.width, rect.size.height);
} completion:^(BOOL finished) {
if (obj.frame.origin.y <= -(self.frame.size.height / self.showedRow)) {
obj.frame = CGRectMake(0, self.frame.size.height, self.frame.size.width, self.frame.size.height / self.showedRow);
self.lastIndex++;
if (self.lastIndex == self.dataArray.count) {
self.lastIndex = 0;
}
obj.tag = self.lastIndex;
if (self.dataArray.count != 0) {
obj.text = self.dataArray[self.lastIndex];
}
if (self.attributedDataArray.count != 0) {
obj.attributedText = self.attributedDataArray[self.lastIndex];
}
}
}];
} else {
obj.frame = CGRectMake(rect.origin.x, rect.origin.y - 1, rect.size.width, rect.size.height);
}
}
}];
}
- (void)tapAction:(UITapGestureRecognizer *)tap {
if ([self.delegate respondsToSelector:@selector(selectedRowAtIndex:jie_carouseNewView:)]) {
[self.delegate selectedRowAtIndex:tap.view.tag jie_carouseNewView:self];
}
}
// 主动释放定时器
- (void)willMoveToSuperview:(UIView *)newSuperview {
[super willMoveToSuperview:newSuperview];
if (!newSuperview && self.timer) {
[self.timer invalidate];
self.timer = nil;
}
}
- (void)dealloc {
NSLog(@"123");
}
@end
使用
#import "FirstVC.h"
#import "Jie_CarouselNewsView.h"
@interface FirstVC ()<Jie_CarouselNewsViewDelegate, Jie_CarouselNewsDataSource>
@property(nonatomic, strong)Jie_CarouselNewsView *newsView;
@end
@implementation FirstVC
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = UIColor.whiteColor;
Jie_CarouselNewsView *newsView = [[Jie_CarouselNewsView alloc] init];
newsView.dataSource = self;
newsView.delegate = self;
newsView.backgroundColor = UIColor.redColor;
[self.view addSubview:newsView];
newsView.frame = CGRectMake(0, 200, self.view.frame.size.width, 100);
_newsView = newsView;
}
- (NSInteger)maxShowedRow:(Jie_CarouselNewsView *)jie_carouseNewView {
return 5;
}
- (NSTimeInterval)carouseNewsTimeInterval:(Jie_CarouselNewsView *)jie_carouseNewView {
return 0.02;
}
- (BOOL)carousenewsScrollPageingEnable:(Jie_CarouselNewsView *)jie_carouseNewView {
return NO;
}
- (NSArray<NSString *> *)carouseNewsData:(Jie_CarouselNewsView *)jie_carouseNewView {
return @[
@"1、到此,一个上下字体无限滚动的轮播",
@"2、当然代码的话写的还是比较烂的",
@"3、到此,一个上下字出",
@"4、到此,一个上下字体无限滚动的",
@"5、到此,我会及",
@"6、到此,一个上改。最后记录本文仅供参考",
@"7、我会及时更改。最后记录本文仅",
@"8、到此,及时更改。最后",
@"9、到此,一出,我会及",
@"10、到烂的,有不足地方请",
@"11、到此,一个更改。最后记录本",
@"12、最后记录本文仅供参考",
@"13、我会及时更改。最后记录本文仅供参考",
@"14、到此,一个时更改。最后记录本文仅供参考",
@"15、最后记录本文仅供参考",
@"16、本文仅供参考",
@"17、当然代码的话写的还是比较烂的",
@"18、我会及时更改。最后记录本文仅供参考",
@"19、一个上下字体无限滚动的",
@"20、到此,我会及时更改。最后记录本文仅供参考",
@"21、一个上改。最后记录本文仅供参考",
@"22、最后记录本文仅供参考",
@"23、到此,及时更改。最后记录本文仅供参考",
@"24、到此,一出,",
@"25、更改。最后记录本文仅供参考",
@"26、最后记录本文仅供参考",
@"27、到此,一个更改。最后记录本文仅供参考"
];
}
- (void)selectedRowAtIndex:(NSInteger)index jie_carouseNewView:(Jie_CarouselNewsView *)jie_carouseNewView {
NSLog(@"选中的行数 === %ld", index);
}
@end
