在网上找到的大部分都是横向的走马灯效果,就自己动手谢了一个上下滚动的。说的准确一点的话可能不算走马灯,文本是有停留的,每次显示一条。不停留连续的走马灯效果正在研究,后期补上。
TableViewCell调用
NSArray * arr = @[@"qwer",@"12345",@"asdfg",@"54321",@"zxcvb",@"09877",@"567889"];
dynamicMessageTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:shoppersCell];
if (cell == nil) {
cell = [[dynamicMessageTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:shoppersCell dataArray:arr];
}
return cell;
Cell
#import "BTableViewCell.h"
@interface dynamicMessageTableViewCell : BTableViewCell
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier dataArray:(NSArray *)titleArray;
//-(void)info:(NSArray *)titleArray;
@end
BBCyclingLabel
#import "dynamicMessageTableViewCell.h"
#import "BBCyclingLabel.h"
@interface dynamicMessageTableViewCell()
{
BBCyclingLabel * _bbCyclingLable;
NSArray * _titleArr;
UITextField * _text;
int a;
int _msgCount;
}
@end
@implementation dynamicMessageTableViewCell
-(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier dataArray:(NSArray *)titleArray
{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
_text = [[UITextField alloc] initWithFrame:CGRectMake(80, 0, SCREEN_WIDTH-80, 30)];
_titleArr = [[NSArray alloc] init];
_titleArr = titleArray;
UIImageView *imagev = [[UIImageView alloc]initWithFrame:CGRectMake(20, 10, 50, 50)];
[imagev setImage:GetImage(@"icon_notice.png")];
[self addSubview:imagev];
[self createUI];
}
return self;
}
-(void)createUI
{
_bbCyclingLable = [[BBCyclingLabel alloc]initWithFrame:CGRectMake(80, 0, SCREEN_WIDTH-80, 30) andTransitionType:BBCyclingLabelTransitionEffectScrollUp];
// [_text addSubview:_bbCyclingLable];
// _text.borderStyle = UITextBorderStyleRoundedRect;
// [self addSubview:_text];
[self addSubview:_bbCyclingLable];
NSTimer *time = [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(change) userInfo:nil repeats:YES];
[time fire];
a = 0;
}
-(void)info:(NSArray *)titleArray
{
_titleArr = titleArray;
}
//数组中的内容仅供测试用,具体内容可以通过后台服务器获取或者写死(数据条数可以改变,我写的是3条)
-(void)change
{
a++;
if (0<=a && a<_titleArr.count) {
_bbCyclingLable.text = [_titleArr objectAtIndex:a];
}else{
a=0;
_bbCyclingLable.text = [_titleArr objectAtIndex:a];
}
}
//
// Copyright 2012 BiasedBit
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//
// Created by Bruno de Carvalho -- @biasedbit / http://biasedbit.com
// Copyright (c) 2012 BiasedBit. All rights reserved.
//
#pragma mark - Enums
typedef enum
{
// User must provide pre-transition and transition blocks
BBCyclingLabelTransitionEffectCustom = 0,
BBCyclingLabelTransitionEffectFadeIn = 1 << 0,
BBCyclingLabelTransitionEffectFadeOut = 1 << 1,
BBCyclingLabelTransitionEffectCrossFade = BBCyclingLabelTransitionEffectFadeIn |
BBCyclingLabelTransitionEffectFadeOut,
BBCyclingLabelTransitionEffectZoomIn = 1 << 2,
BBCyclingLabelTransitionEffectZoomOut = 1 << 3,
BBCyclingLabelTransitionEffectScaleFadeOut = BBCyclingLabelTransitionEffectFadeIn |
BBCyclingLabelTransitionEffectFadeOut |
BBCyclingLabelTransitionEffectZoomOut,
BBCyclingLabelTransitionEffectScaleFadeIn = BBCyclingLabelTransitionEffectFadeIn |
BBCyclingLabelTransitionEffectFadeOut |
BBCyclingLabelTransitionEffectZoomIn,
// These two move the entering label from above/below to center and exiting label up/down without cross-fade
// It's a good idea to set the clipsToBounds property of the BBCyclingLabel to true and use this in a confined space
BBCyclingLabelTransitionEffectScrollUp = 1 << 4,
BBCyclingLabelTransitionEffectScrollDown = 1 << 5,
BBCyclingLabelTransitionEffectDefault = BBCyclingLabelTransitionEffectCrossFade
} BBCyclingLabelTransitionEffect;
#pragma mark - Custom types
typedef void(^BBCyclingLabelPreTransitionBlock)(UILabel* labelToEnter);
typedef void(^BBCyclingLabelTransitionBlock)(UILabel* labelToExit, UILabel* labelToEnter);
#pragma mark -
@interface BBCyclingLabel : UIView
#pragma mark Public properties
@property(assign, nonatomic) BBCyclingLabelTransitionEffect transitionEffect;
@property(copy, nonatomic) BBCyclingLabelPreTransitionBlock preTransitionBlock;
@property(copy, nonatomic) BBCyclingLabelTransitionBlock transitionBlock;
@property(assign, nonatomic) NSTimeInterval transitionDuration;
// Same properties as UILabel, these will be propagated to the underlying labels
@property(copy, nonatomic) NSString* text;
@property(strong, nonatomic) UIFont* font;
@property(strong, nonatomic) UIColor* textColor;
@property(strong, nonatomic) UIColor* shadowColor;
@property(assign, nonatomic) CGSize shadowOffset;
@property(assign, nonatomic) UITextAlignment textAlignment;
@property(assign, nonatomic) UILineBreakMode lineBreakMode;
@property(assign, nonatomic) NSInteger numberOfLines;
@property(assign, nonatomic) BOOL adjustsFontSizeToFitWidth;
@property(assign, nonatomic) CGFloat minimumFontSize;
@property(assign, nonatomic) UIBaselineAdjustment baselineAdjustment;
#pragma mark Creation
- (id)initWithFrame:(CGRect)frame andTransitionType:(BBCyclingLabelTransitionEffect)transitionEffect;
#pragma mark Public methods
/*! Sets the text for the next label and performs a transition between current and next label (if animated is YES) */
- (void)setText:(NSString*)text animated:(BOOL)animated;
@end
//
// Copyright 2012 BiasedBit
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
//
// Created by Bruno de Carvalho -- @biasedbit / http://biasedbit.com
// Copyright (c) 2012 BiasedBit. All rights reserved.
//
#import "BBCyclingLabel.h"
#pragma mark - Constants
NSTimeInterval const kBBCyclingLabelDefaultTransitionDuration = 0.3;
#pragma mark -
@interface BBCyclingLabel ()
{
NSUInteger _currentLabelIndex;
}
#pragma mark Private properties
@property(strong, nonatomic) NSArray* labels;
@property(strong, nonatomic) UILabel* currentLabel;
#pragma mark Private helpers
- (void)setupWithEffect:(BBCyclingLabelTransitionEffect)effect andDuration:(NSTimeInterval)duration;
- (void)prepareTransitionBlocks;
- (NSUInteger)nextLabelIndex;
- (void)resetLabel:(UILabel*)label;
@end
#pragma mark -
@implementation BBCyclingLabel
#pragma mark Property synthesizers
@synthesize transitionEffect = _transitionEffect;
@synthesize preTransitionBlock = _preTransitionBlock;
@synthesize transitionBlock = _transitionBlock;
@synthesize transitionDuration = _transitionDuration;
// Private
@synthesize labels = _labels;
@synthesize currentLabel = _currentLabel;
#pragma mark Creation
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self != nil) {
[self setupWithEffect:BBCyclingLabelTransitionEffectDefault
andDuration:kBBCyclingLabelDefaultTransitionDuration];
}
return self;
}
- (id)initWithCoder:(NSCoder*)coder
{
self = [super initWithCoder:coder];
if (self != nil) {
[self setupWithEffect:BBCyclingLabelTransitionEffectDefault
andDuration:kBBCyclingLabelDefaultTransitionDuration];
}
return self;
}
- (id)initWithFrame:(CGRect)frame andTransitionType:(BBCyclingLabelTransitionEffect)transitionEffect;
{
self = [super initWithFrame:frame];
if (self != nil) {
[self setupWithEffect:transitionEffect
andDuration:kBBCyclingLabelDefaultTransitionDuration];
}
return self;
}
#pragma mark Manual property accessors
- (void)setTransitionEffect:(BBCyclingLabelTransitionEffect)transitionEffect
{
_transitionEffect = transitionEffect;
[self prepareTransitionBlocks];
}
- (NSString*)text
{
return _currentLabel.text;
}
- (void)setText:(NSString*)text
{
[self setText:text animated:YES];
}
- (UIFont*)font
{
return _currentLabel.font;
}
- (void)setFont:(UIFont*)font
{
for (UILabel* label in _labels) {
label.font = font;
}
}
- (UIColor*)textColor
{
return _currentLabel.textColor;
}
- (void)setTextColor:(UIColor*)textColor
{
for (UILabel* label in _labels) {
label.textColor = textColor;
}
}
- (UIColor*)shadowColor
{
return _currentLabel.shadowColor;
}
- (void)setShadowColor:(UIColor*)shadowColor
{
for (UILabel* label in _labels) {
label.shadowColor = shadowColor;
}
}
- (CGSize)shadowOffset
{
return _currentLabel.shadowOffset;
}
- (void)setShadowOffset:(CGSize)shadowOffset
{
for (UILabel* label in _labels) {
label.shadowOffset = shadowOffset;
}
}
- (UITextAlignment)textAlignment
{
return _currentLabel.textAlignment;
}
- (void)setTextAlignment:(UITextAlignment)textAlignment
{
for (UILabel* label in _labels) {
label.textAlignment = textAlignment;
}
}
- (UILineBreakMode)lineBreakMode
{
return _currentLabel.lineBreakMode;
}
- (void)setLineBreakMode:(UILineBreakMode)lineBreakMode
{
for (UILabel* label in _labels) {
label.lineBreakMode = lineBreakMode;
}
}
- (NSInteger)numberOfLines
{
return _currentLabel.numberOfLines;
}
- (void)setNumberOfLines:(NSInteger)numberOfLines
{
for (UILabel* label in _labels) {
label.numberOfLines = numberOfLines;
}
}
- (BOOL)adjustsFontSizeToFitWidth
{
return _currentLabel.adjustsFontSizeToFitWidth;
}
- (void)setAdjustsFontSizeToFitWidth:(BOOL)adjustsFontSizeToFitWidth
{
for (UILabel* label in _labels) {
label.adjustsFontSizeToFitWidth = adjustsFontSizeToFitWidth;
}
}
- (CGFloat)minimumFontSize
{
return _currentLabel.minimumFontSize;
}
- (void)setMinimumFontSize:(CGFloat)minimumFontSize
{
for (UILabel* label in _labels) {
label.minimumFontSize = minimumFontSize;
}
}
- (UIBaselineAdjustment)baselineAdjustment
{
return _currentLabel.baselineAdjustment;
}
- (void)setBaselineAdjustment:(UIBaselineAdjustment)baselineAdjustment
{
for (UILabel* label in _labels) {
label.baselineAdjustment = baselineAdjustment;
}
}
#pragma mark Public methods
- (void)setText:(NSString*)text animated:(BOOL)animated
{
NSUInteger nextLabelIndex = [self nextLabelIndex];
UILabel* nextLabel = [_labels objectAtIndex:nextLabelIndex];
UILabel* previousLabel = _currentLabel;
nextLabel.text = text;
// Resetting the label state ensures we can change the transition type without extra code on pre-transition block.
// Without it a transition that has no alpha changes would have to ensure alpha = 1 on pre-transition block (as
// well as with every other possible animatable property)
[self resetLabel:nextLabel];
// Update both current label index and current label pointer
self.currentLabel = nextLabel;
_currentLabelIndex = nextLabelIndex;
// Prepare the next label before the transition animation
if (_preTransitionBlock != nil) {
_preTransitionBlock(nextLabel);
} else {
// If no pre-transition block is set, prepare the next label for a cross-fade
nextLabel.alpha = 0;
}
// Unhide the label that's about to be shown
nextLabel.hidden = NO;
void (^changeBlock)() = ^() {
// Perform the user provided changes
if (_transitionBlock != nil) {
_transitionBlock(previousLabel, nextLabel);
} else {
// If no transition block is set, perform a simple cross-fade
previousLabel.alpha = 0;
nextLabel.alpha = 1;
}
};
void (^completionBlock)(BOOL) = ^(BOOL finished) {
if (finished) {
// TODO this is kind of bugged since all transitions that include affine transforms always return finished
// as true, even when it doesn't finish...
previousLabel.hidden = YES;
}
};
if (animated) {
// Animate the transition between both labels
[UIView animateWithDuration:_transitionDuration animations:changeBlock completion:completionBlock];
} else {
changeBlock();
completionBlock(YES);
}
}
#pragma mark Private helpers
- (void)setupWithEffect:(BBCyclingLabelTransitionEffect)effect andDuration:(NSTimeInterval)duration
{
NSUInteger size = 2;
NSMutableArray* labels = [NSMutableArray arrayWithCapacity:size];
for (NSUInteger i = 0; i < size; i++) {
UILabel* label = [[UILabel alloc] initWithFrame:self.bounds];
[self addSubview:label];
label.backgroundColor = [UIColor clearColor];
label.hidden = YES;
label.numberOfLines = 0;
[labels addObject:label];
}
_currentLabelIndex = 0;
self.currentLabel = [labels objectAtIndex:0];
self.labels = labels;
_currentLabel.hidden = NO;
self.transitionEffect = effect;
self.transitionDuration = duration;
}
- (void)prepareTransitionBlocks
{
//if matches custom
if (_transitionEffect == BBCyclingLabelTransitionEffectCustom) {
return;
}
BBCyclingLabelTransitionEffect type = _transitionEffect;
self.preTransitionBlock = ^(UILabel* labelToEnter) {
if (type & BBCyclingLabelTransitionEffectFadeIn) {
labelToEnter.alpha = 0;
}
if (type & BBCyclingLabelTransitionEffectZoomIn) {
labelToEnter.transform = CGAffineTransformMakeScale(0.5, 0.5);
}
if (type & (BBCyclingLabelTransitionEffectScrollUp | BBCyclingLabelTransitionEffectScrollDown)) {
CGRect frame = labelToEnter.frame;
if (type & BBCyclingLabelTransitionEffectScrollUp) {
frame.origin.y = self.bounds.size.height;
}
if (type & BBCyclingLabelTransitionEffectScrollDown) {
frame.origin.y = 0 - frame.size.height;
}
labelToEnter.frame = frame;
}
};
self.transitionBlock = ^(UILabel* labelToExit, UILabel* labelToEnter) {
if (type & BBCyclingLabelTransitionEffectFadeIn) {
labelToEnter.alpha = 1;
}
if (type & BBCyclingLabelTransitionEffectFadeOut) {
labelToExit.alpha = 0;
}
if (type & BBCyclingLabelTransitionEffectZoomOut) {
labelToExit.transform = CGAffineTransformMakeScale(1.5, 1.5);
}
if (type & BBCyclingLabelTransitionEffectZoomIn) {
labelToEnter.transform = CGAffineTransformIdentity;
}
if (type & (BBCyclingLabelTransitionEffectScrollUp | BBCyclingLabelTransitionEffectScrollDown)) {
CGRect frame = labelToExit.frame;
CGRect enterFrame = labelToEnter.frame;
if (type & BBCyclingLabelTransitionEffectScrollUp) {
frame.origin.y = 0 - frame.size.height;
enterFrame.origin.y = roundf((self.bounds.size.height / 2) - (enterFrame.size.height / 2));
}
if (type & BBCyclingLabelTransitionEffectScrollDown) {
frame.origin.y = self.bounds.size.height;
enterFrame.origin.y = roundf((self.bounds.size.height / 2) - (enterFrame.size.height / 2));
}
labelToExit.frame = frame;
labelToEnter.frame = enterFrame;
}
};
}
- (NSUInteger)nextLabelIndex
{
return (_currentLabelIndex + 1) % [_labels count];
}
- (void)resetLabel:(UILabel*)label
{
label.alpha = 1;
label.transform = CGAffineTransformIdentity;
label.frame = self.bounds;
}
@end