簡(jiǎn)述
SKAutoScrollLabel是一個(gè)同時(shí)支持水平/垂直兩種類型的“跑馬燈”效果的自動(dòng)滾動(dòng)UILabel。在滾動(dòng)的邊緣使用了梯度褪色來解決滾動(dòng)邊緣生硬的效果問題沙庐,總體效果呈現(xiàn)出混然天成的感覺鲤妥,并且使用簡(jiǎn)單方便。如果你覺得還不錯(cuò)拱雏,請(qǐng)star支持一下吧~

效果圖
如何開始
1.從GitHub上Clone-->SKAutoScrollLabel棉安,然后查看Demo
2.直接將目錄下的SKAutoScrollLabel拷貝到工程中,或在podfile文件夾中添加 pod 'SKAutoScrollLabel'
使用方法
初始化
SKAutoScrollLabel * leftLabel = [[SKAutoScrollLabel alloc] initWithFrame:CGRectMake(50, 50, [UIScreen mainScreen].bounds.size.width - 100, 50)];
[self.view addSubview:leftLabel];
基本設(shè)置
leftLabel.backgroundColor = [UIColor blackColor];// 背景色
leftLabel.textColor = [UIColor whiteColor];// 字體顏色
leftLabel.font = [UIFont systemFontOfSize:16];// 字體大小
leftLabel.direction = SK_AUTOSCROLL_DIRECTION_LEFT;// 滾動(dòng)方向铸抑,這是向左滾動(dòng)
leftLabel.text = text;// 顯示內(nèi)容
實(shí)現(xiàn)
※ 這里僅列出關(guān)鍵步驟贡耽,具體方法請(qǐng)查閱源碼
- 我們需要?jiǎng)?chuàng)建一個(gè)數(shù)組,來存放我們滾動(dòng)時(shí)所需要展示的label鹊汛,這里我們只創(chuàng)建兩個(gè)label存放到數(shù)組中即可(滾動(dòng)只需要兩個(gè)即可達(dá)成持續(xù)跑馬燈的效果)
// 創(chuàng)建label數(shù)組
NSMutableSet * labelSet = [[NSMutableSet alloc] init];
for (NSInteger i = 0; i < kLabelCount; i++) {
UILabel * label = [UILabel new];
label.backgroundColor = [UIColor clearColor];
label.autoresizingMask = self.autoresizingMask;
label.frame = CGRectMake(0, 0, 50, 50);
[self.scrollView addSubview:label];
[labelSet addObject:label];
}
self.labels = [labelSet.allObjects copy];
2.區(qū)分水平和垂直的UILabel
static void each_object(NSArray *objects, void (^block)(UILabel * label)) {
for (UILabel * label in objects) {
block(label);
}
}
__block float offset = 0;
// 遍歷label數(shù)組中的元素
each_object(self.labels, ^(UILabel *label) {
[label sizeToFit];
CGRect frame = label.frame;
// 垂直
if (self.direction != SK_AUTOSCROLL_DIRECTION_RIGHT && self.direction != SK_AUTOSCROLL_DIRECTION_LEFT) {
// 動(dòng)態(tài)獲取長(zhǎng)度和高度, 以此達(dá)到將label垂直的目的
NSDictionary * attribute = [NSDictionary dictionaryWithObjectsAndKeys:self.font,NSFontAttributeName, nil];
CGSize sizeWord = [@"一" boundingRectWithSize:self.bounds.size options:NSStringDrawingUsesFontLeading | NSStringDrawingUsesLineFragmentOrigin attributes:attribute context:nil].size;
CGFloat wordWidth = sizeWord.width;
CGSize sizeStr = [self.text boundingRectWithSize:CGSizeMake(wordWidth, CGFLOAT_MAX) options:NSStringDrawingUsesFontLeading | NSStringDrawingUsesLineFragmentOrigin attributes:attribute context:nil].size;
CGFloat wordHeight = sizeStr.height;
frame.origin = CGPointMake((CGRectGetWidth(self.frame) / 2) - (wordWidth / 2), offset);
frame.size = CGSizeMake(wordWidth, wordHeight);
label.frame = frame;
label.numberOfLines = 0;
offset += CGRectGetHeight(label.bounds) + self.labelSpacing;
} else {// 水平
frame.origin = CGPointMake(offset, 0);
frame.size.height = CGRectGetHeight(self.bounds);
label.frame = frame;
offset += CGRectGetWidth(label.bounds) + self.labelSpacing;
// 重新定位label在scrollview中的位置
label.center = CGPointMake(label.center.x, roundf(self.center.y - CGRectGetMinY(self.frame)));
}
});
3.判斷滾動(dòng)條件蒲赂,是否允許滾動(dòng)
// (水平方向) 判斷當(dāng)前scrollLabel是否大于self的寬度,如果是就開始滾動(dòng)
if (CGRectGetWidth(self.scrollLabel.bounds) > CGRectGetWidth(self.bounds)) {
CGSize size = CGSizeMake(CGRectGetWidth(self.scrollLabel.bounds) + CGRectGetWidth(self.bounds) + self.labelSpacing, CGRectGetHeight(self.bounds));
self.scrollView.contentSize = size;
EACH_LABEL(hidden, NO);
[self applyGradientMaskForFadeLength:kDefaultFadeLength enableFade:self.scrolling];
[self scrollLabelIfNeeded];
} else if (CGRectGetHeight(self.scrollLabel.bounds) > CGRectGetHeight(self.bounds)) {// (垂直方向) 判斷當(dāng)前scrollLabel是否大于self的高度刁憋,如果是就開始滾動(dòng)
CGSize size = CGSizeMake(CGRectGetWidth(self.bounds), CGRectGetHeight(self.scrollLabel.bounds) + self.labelSpacing);
self.scrollView.contentSize = size;
EACH_LABEL(hidden, NO);
[self applyGradientMaskForFadeLength:kDefaultFadeLength enableFade:self.scrolling];
[self scrollLabelIfNeeded];
} else {
// 隱藏其他label
EACH_LABEL(hidden, self.scrollLabel != label);
// 調(diào)整scrollView和scrollLabel
self.scrollView.contentSize = self.bounds.size;
self.scrollLabel.frame = self.bounds;
self.scrollLabel.hidden = NO;
self.scrollLabel.textAlignment = NSTextAlignmentCenter;
[self.scrollView.layer removeAllAnimations];
[self applyGradientMaskForFadeLength:0 enableFade:NO];
}
4.自動(dòng)滾動(dòng)動(dòng)畫
switch (self.direction) {// 滾動(dòng)方向
case SK_AUTOSCROLL_DIRECTION_LEFT:
self.scrollView.contentOffset = CGPointZero;
break;
case SK_AUTOSCROLL_DIRECTION_RIGHT:
self.scrollView.contentOffset = CGPointMake(width + self.labelSpacing, 0);
break;
case SK_AUTOSCROLL_DIRECTION_TOP:
self.scrollView.contentOffset = CGPointZero;
break;
case SK_AUTOSCROLL_DIRECTION_BOTTOM:
self.scrollView.contentOffset = CGPointMake(0, height - 10 - CGRectGetHeight(self.bounds));
break;
}
// 滾動(dòng)動(dòng)畫, UIViewAnimationOptionRepeat一直重復(fù)動(dòng)畫
[UIView animateWithDuration:duration delay:self.autoScrollInterval options:UIViewAnimationOptionRepeat animations:^{
switch (self.direction) {
case SK_AUTOSCROLL_DIRECTION_LEFT:
self.scrollView.contentOffset = CGPointMake(width + self.labelSpacing, 0);
break;
case SK_AUTOSCROLL_DIRECTION_RIGHT:
self.scrollView.contentOffset = CGPointZero;
break;
case SK_AUTOSCROLL_DIRECTION_TOP:
self.scrollView.contentOffset = CGPointMake(0, CGRectGetHeight(self.scrollLabel.bounds) + self.labelSpacing);
break;
case SK_AUTOSCROLL_DIRECTION_BOTTOM:
self.scrollView.contentOffset = CGPointZero;
break;
}
} completion:^(BOOL finished) {
_scrolling = NO;
// 移除陰影
[self applyGradientMaskForFadeLength:kDefaultFadeLength enableFade:NO];
// 完成后循調(diào)用
if (finished) {
[self performSelector:@selector(scrollLabelIfNeeded)];
}
}];
5.使用CAGradientLayer在滾動(dòng)邊緣的制造梯度褪色效果
// 創(chuàng)建梯度mask和消失長(zhǎng)度
CAGradientLayer * gradientMask = [CAGradientLayer layer];
gradientMask.bounds = self.layer.bounds;
gradientMask.position = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
gradientMask.shouldRasterize = YES;
gradientMask.rasterizationScale = [UIScreen mainScreen].scale;
CGFloat fadePoint = 0;
// 垂直方向的梯度褪色
if (self.direction != SK_AUTOSCROLL_DIRECTION_RIGHT && self.direction != SK_AUTOSCROLL_DIRECTION_LEFT) {
gradientMask.startPoint = CGPointMake(CGRectGetMidX(self.frame), 0);
gradientMask.endPoint = CGPointMake(CGRectGetMidX(self.frame), 1);
fadePoint = fadeLength / CGRectGetHeight(self.bounds);
// 水平方向的梯度褪色
} else {
gradientMask.startPoint = CGPointMake(0, CGRectGetMidY(self.frame));
gradientMask.endPoint = CGPointMake(1, CGRectGetMidY(self.frame));
fadePoint = fadeLength / CGRectGetWidth(self.bounds);
}
// 設(shè)置漸變mask顏色和位置
id transparent = (id)[UIColor clearColor].CGColor;
id opaque = (id)[UIColor blackColor].CGColor;
gradientMask.colors = @[transparent, opaque, opaque, transparent];
// 計(jì)算褪色
NSNumber * leftFadePoint = @(fadePoint);
NSNumber * rightFadePoint = @(1 - fadePoint);
if (!fade) {
switch (self.direction) {
case SK_AUTOSCROLL_DIRECTION_LEFT:
leftFadePoint = @0;
break;
case SK_AUTOSCROLL_DIRECTION_RIGHT:
leftFadePoint = @0;
rightFadePoint = @1;
break;
case SK_AUTOSCROLL_DIRECTION_TOP:
leftFadePoint = @0;
break;
case SK_AUTOSCROLL_DIRECTION_BOTTOM:
leftFadePoint = @0;
rightFadePoint = @1;
break;
}
}
// 將計(jì)算結(jié)果交給mask
gradientMask.locations = @[@0, leftFadePoint, rightFadePoint, @1];
[CATransaction begin];
[CATransaction setDisableActions:YES];
self.layer.mask = gradientMask;
[CATransaction commit];
感謝你花時(shí)間閱讀以上內(nèi)容, 如果這個(gè)項(xiàng)目能夠幫助到你滥嘴,記得告訴我
Email: shevakuilin@gmail.com