iOS

滚动显示Label优化版本

2017-02-10  本文已影响125人  ys简单0

.h

#import <UIKit/UIKit.h>

typedef NS_ENUM(NSInteger, BBFlashCtntSpeed) {

BBFlashCtntSpeedSlow = -1,

BBFlashCtntSpeedMild,

BBFlashCtntSpeedFast

};

@interface BBFlashCtntLabel : UIView

@property (nonatomic, strong) NSString *text;

@property (nonatomic, strong) UIFont *font;        // 默认:system(15)

@property (nonatomic, strong) UIColor *textColor;

@property (nonatomic, strong) NSAttributedString *attributedText;

@property (nonatomic, assign) BBFlashCtntSpeed speed;

// 循环滚动次数(为0时无限滚动)

@property (nonatomic, assign) NSUInteger repeatCount;

@property (nonatomic, assign) CGFloat leastInnerGap;

- (void)reloadView;

@end

.m

#import "BBFlashCtntLabel.h"

@interface BBFlashCtntLabel()

{

BOOL seted;

BOOL moveNeed;

CGFloat rate;

}

@property (nonatomic, strong) UIView *innerContainer;

@end

@implementation BBFlashCtntLabel

- (void)awakeFromNib

{

[super awakeFromNib];

self.font = [UIFont systemFontOfSize:15];

self.textColor = [UIColor blackColor];

self.speed = BBFlashCtntSpeedMild;

self.repeatCount = 0;

self.leastInnerGap = 10.f;

self.clipsToBounds = YES;

rate = 80.f;

[self setup];

}

- (instancetype)initWithFrame:(CGRect)frame

{

if (self = [super initWithFrame:frame]) {

self.font = [UIFont systemFontOfSize:15];

self.textColor = [UIColor blackColor];

self.speed = BBFlashCtntSpeedMild;

self.repeatCount = 0;

self.leastInnerGap = 10.f;

self.clipsToBounds = YES;

[self setup];

}

return self;

}

- (void)setSpeed:(BBFlashCtntSpeed)speed

{

_speed = speed;

switch (_speed) {

case BBFlashCtntSpeedFast:

rate = 90.;

break;

case BBFlashCtntSpeedMild:

rate = 75;

break;

case BBFlashCtntSpeedSlow:

rate = 40.;

break;

default:

break;

}

[self reloadView];

}

- (void)setLeastInnerGap:(CGFloat)leastInnerGap

{

_leastInnerGap = leastInnerGap;

[self reloadView];

}

- (void)setText:(NSString *)text

{

_text = text;

_attributedText = nil;

[self reloadView];

}

- (void)setAttributedText:(NSAttributedString *)attributedText

{

_attributedText = [self setAttributedTextDefaultFont:attributedText];

_text = nil;

[self reloadView];

}

- (NSAttributedString *)setAttributedTextDefaultFont:(NSAttributedString *)attrText

{

NSMutableAttributedString *rtn = [[NSMutableAttributedString alloc] initWithAttributedString:attrText];

void (^enumerateBlock)(id, NSRange, BOOL *) = ^(id value, NSRange range, BOOL *stop) {

if (!value || [value isKindOfClass:[NSNull class]]) {

[rtn addAttribute:NSFontAttributeName

value:self.font

range:range];

}

};

[rtn enumerateAttribute:NSFontAttributeName

inRange:NSMakeRange(0, rtn.string.length)

options:0

usingBlock:enumerateBlock];

return rtn;

}

- (void)setFont:(UIFont *)font

{

_font = font;

[self reloadView];

}

- (void)setTextColor:(UIColor *)textColor

{

_textColor = textColor;

[self reloadView];

}

- (void)setup

{

if (seted) {

return ;

}

self.innerContainer = [[UIView alloc] initWithFrame:self.bounds];

self.innerContainer.backgroundColor = [UIColor clearColor];

self.innerContainer.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;

[self addSubview:self.innerContainer];

seted = YES;

}

- (void)reloadView

{

[self.innerContainer.layer removeAnimationForKey:@"move"];

for (UIView *sub in self.innerContainer.subviews) {

if ([sub isKindOfClass:[UILabel class]]) {

[sub removeFromSuperview];

}

}

CGFloat width = [self evaluateContentWidth];

moveNeed = width > self.bounds.size.width;

CGRect f = CGRectMake(0, 0, width, self.bounds.size.height);

UILabel *label = [[UILabel alloc] initWithFrame:f];

label.textAlignment = NSTextAlignmentCenter;

label.backgroundColor = [UIColor clearColor];

label.text = self.text;

label.textColor = self.textColor;

label.font = self.font;

[self.innerContainer addSubview:label];

if (moveNeed) {

CGRect f1 = CGRectMake(width + self.leastInnerGap, 0, width, f.size.height);

UILabel *next = [[UILabel alloc] initWithFrame:f1];

next.backgroundColor = [UIColor clearColor];

next.textAlignment = NSTextAlignmentCenter;

if (self.text) {

next.text = self.text;

next.textColor = self.textColor;

next.font = self.font;

} else {

next.attributedText = self.attributedText;

}

[self.innerContainer addSubview:next];

CAKeyframeAnimation *moveAnimation = [CAKeyframeAnimation animationWithKeyPath:@"transform.translation.x"];

moveAnimation.keyTimes = @[@0., @1.0];

moveAnimation.duration = width / rate;

moveAnimation.values = @[@0, @(- width - self.leastInnerGap)];

moveAnimation.repeatCount = self.repeatCount == 0 ? INT16_MAX : self.repeatCount;

moveAnimation.timingFunction = [CAMediaTimingFunction functionWithName:@"linear"];

[self.innerContainer.layer addAnimation:moveAnimation forKey:@"move"];

}

}

- (CGFloat)evaluateContentWidth

{

CGFloat width = 0.f;

NSStringDrawingOptions options = NSStringDrawingTruncatesLastVisibleLine |

NSStringDrawingUsesLineFragmentOrigin |

NSStringDrawingUsesFontLeading;

if (_text.length > 0) {

NSDictionary *attr = @{NSFontAttributeName : self.font};

CGSize size = [_text boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, self.bounds.size.height) options:options attributes:attr context:nil].size;

width = size.width;

} else if (_attributedText.length > 0) {

CGSize size = [_attributedText boundingRectWithSize:CGSizeMake(CGFLOAT_MAX, self.bounds.size.height) options:options context:nil].size;

width = size.width;

}

return width;

}

@end

在控制器中使用时:

BBFlashCtntLabel *label = [[BBFlashCtntLabel alloc]initWithFrame:CGRectMake(50, 100, 150, 50)];

label.text = @"大猴子小猴子,大小猴子,小大猴子,子猴大小,猴子小大";

label.textColor = [UIColor magentaColor];

label.speed = -1;

label.leastInnerGap = 10;

[self.view addSubview:label];

这样就实现真正意义上的循环滚动显示了.

上一篇 下一篇

猜你喜欢

热点阅读