项目中用到这种效果,索性写了一个通用的组件,可以支持从左到右、从右到左、从上到下、从下到上 4个方向的滚动。
有不完善的地方请指正,谢谢
//
// ScrollingTextView.h
// ScrollingText
//
// Created by Hunk on 14/12/1.
// Copyright (c) 2014年 Hunk. All rights reserved.
//
#import <UIKit/UIKit.h>
typedef NS_ENUM(NSInteger, ScrollDirection)
{
ScrollDirectionFromRightToLeft = 0,
ScrollDirectionFromLeftToRight,
ScrollDirectionFromTopToBottom,
ScrollDirectionFromBottomToTop
};
@interface ScrollingTextView : UIView
{}
/**
* Text array
*
* Default is DefaultScrollingText-1 and DefaultScrollingText-2.
*/
@property (nonatomic, strong) NSArray *scrollingTextArray;
/**
* Scroll direction
*
* Default is ScrollDirectionFromRightToLeft.
*/
@property (nonatomic, assign) ScrollDirection scrollDirection;
/**
* Scroll duration
*
* Default is 2.0 seconds.
*/
@property (nonatomic, assign) NSTimeInterval duration;
/**
* Animating flag
*
* Default is NO.
*/
@property (nonatomic, assign) BOOL isAnimating;
/**
* Start animating
*
* Before calling this function, set scrollingTextArray, scrollDirection and duration first.
*/
- (void)startAnimating;
/**
* Stop animating
*
* @return Stop animating successfully or not.
*/
- (BOOL)stopAnimating;
@end
//
// ScrollingTextView.m
// ScrollingText
//
// Created by Hunk on 14/12/1.
// Copyright (c) 2014年 Hunk. All rights reserved.
//
#import "ScrollingTextView.h"
@interface ScrollingTextView ()
{
// Text label
UILabel *_textLabel[2];
// Text index
NSInteger _index;
BOOL _animatingEnable;
}
@end
@implementation ScrollingTextView
@synthesize scrollingTextArray = _scrollingTextArray;
@synthesize scrollDirection = _scrollDirection;
@synthesize duration = _duration;
@synthesize isAnimating = _isAnimating;
- (instancetype)initWithFrame:(CGRect)frame
{
if(self = [super initWithFrame:frame])
{
[self setBackgroundColor:[UIColor clearColor]];
[self setClipsToBounds:YES];
[self setOpaque:YES];
// Text label
_textLabel[0] = [self textLabelWithFrame:self.bounds];
[self addSubview:_textLabel[0]];
_textLabel[1] = [self textLabelWithFrame:CGRectMake(CGRectGetWidth(self.bounds), 0.0, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds))];
[self addSubview:_textLabel[1]];
// Initialize data
self.scrollingTextArray = @[@"DefaultScrollingText-1", @"DefaultScrollingText-2"];
self.scrollDirection = ScrollDirectionFromLeftToRight;
self.duration = 2.0;
self.isAnimating = NO;
_index = 0;
_animatingEnable = YES;
}
return self;
}
#pragma mark -
#pragma mark Set scroll text array
-(void)setScrollingTextArray:(NSArray *)scrollingTextArray
{
if(_scrollingTextArray != scrollingTextArray)
{
_scrollingTextArray = scrollingTextArray;
}
if([_scrollingTextArray count] >= 2)
{
[_textLabel[0] setText:[_scrollingTextArray objectAtIndex:0]];
[_textLabel[1] setText:[_scrollingTextArray objectAtIndex:1]];
_index = 1;
}
}
#pragma mark -
#pragma mark Set scroll direction
- (void)setScrollDirection:(ScrollDirection)scrollDirection
{
_scrollDirection = scrollDirection;
switch(self.scrollDirection)
{
case ScrollDirectionFromRightToLeft:
{
[_textLabel[0] setFrame:self.bounds];
[_textLabel[1] setFrame:CGRectMake(CGRectGetWidth(self.bounds), 0.0, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds))];
}
break;
case ScrollDirectionFromLeftToRight:
{
[_textLabel[0] setFrame:self.bounds];
[_textLabel[1] setFrame:CGRectMake(-CGRectGetWidth(self.bounds), 0.0, CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds))];
}
break;
case ScrollDirectionFromTopToBottom:
{
[_textLabel[0] setFrame:self.bounds];
[_textLabel[1] setFrame:CGRectMake(0.0, -CGRectGetHeight(self.bounds), CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds))];
}
break;
case ScrollDirectionFromBottomToTop:
{
[_textLabel[0] setFrame:self.bounds];
[_textLabel[1] setFrame:CGRectMake(0.0, CGRectGetHeight(self.bounds), CGRectGetWidth(self.bounds), CGRectGetHeight(self.bounds))];
}
break;
default:
break;
}
}
#pragma mark -
#pragma mark Start animating
- (void)startAnimating
{
_animatingEnable = YES;
[self setIsAnimating:YES];
[UIView animateWithDuration:self.duration
delay:0.0
options:UIViewAnimationOptionCurveLinear
animations:^{
switch(self.scrollDirection)
{
case ScrollDirectionFromRightToLeft:
{
[_textLabel[0] setFrame:CGRectOffset(_textLabel[0].frame, -CGRectGetWidth(self.bounds), 0.0)];
[_textLabel[1] setFrame:CGRectOffset(_textLabel[1].frame, -CGRectGetWidth(self.bounds), 0.0)];
}
break;
case ScrollDirectionFromLeftToRight:
{
[_textLabel[0] setFrame:CGRectOffset(_textLabel[0].frame, CGRectGetWidth(self.bounds), 0.0)];
[_textLabel[1] setFrame:CGRectOffset(_textLabel[1].frame, CGRectGetWidth(self.bounds), 0.0)];
}
break;
case ScrollDirectionFromTopToBottom:
{
[_textLabel[0] setFrame:CGRectOffset(_textLabel[0].frame, 0.0, CGRectGetHeight(self.bounds))];
[_textLabel[1] setFrame:CGRectOffset(_textLabel[1].frame, 0.0, CGRectGetHeight(self.bounds))];
}
break;
case ScrollDirectionFromBottomToTop:
{
[_textLabel[0] setFrame:CGRectOffset(_textLabel[0].frame, 0.0, -CGRectGetHeight(self.bounds))];
[_textLabel[1] setFrame:CGRectOffset(_textLabel[1].frame, 0.0, -CGRectGetHeight(self.bounds))];
}
break;
default:
break;
}
}
completion:^(BOOL finished) {
[self setIsAnimating:NO];
if(YES == _animatingEnable)
{
[self animationDidStoped];
}
}];
}
- (BOOL)stopAnimating
{
if(self.isAnimating)
{
_animatingEnable = NO;
return YES;
}
return NO;
}
#pragma makr -
#pragma makr Private method
// Animation stoped
- (void)animationDidStoped
{
_index++;
if(_index >= [_scrollingTextArray count])
{
_index = 0;
}
if([_scrollingTextArray count] > _index)
{
switch(self.scrollDirection)
{
case ScrollDirectionFromRightToLeft:
{
if(_textLabel[0].frame.origin.x < 0)
{
[_textLabel[0] setFrame:CGRectOffset(_textLabel[0].frame, 2 * CGRectGetWidth(self.bounds), 0.0)];
[_textLabel[0] setText:[_scrollingTextArray objectAtIndex:_index]];
}
else
{
[_textLabel[1] setFrame:CGRectOffset(_textLabel[1].frame, 2 * CGRectGetWidth(self.bounds), 0.0)];
[_textLabel[1] setText:[_scrollingTextArray objectAtIndex:_index]];
}
}
break;
case ScrollDirectionFromLeftToRight:
{
if(_textLabel[0].frame.origin.x >= CGRectGetWidth(self.bounds))
{
[_textLabel[0] setFrame:CGRectOffset(_textLabel[0].frame, -2 * CGRectGetWidth(self.bounds), 0.0)];
[_textLabel[0] setText:[_scrollingTextArray objectAtIndex:_index]];
}
else
{
[_textLabel[1] setFrame:CGRectOffset(_textLabel[1].frame, -2 * CGRectGetWidth(self.bounds), 0.0)];
[_textLabel[1] setText:[_scrollingTextArray objectAtIndex:_index]];
}
}
break;
case ScrollDirectionFromTopToBottom:
{
if(_textLabel[0].frame.origin.y >= CGRectGetHeight(self.bounds))
{
[_textLabel[0] setFrame:CGRectOffset(_textLabel[0].frame, 0.0, -2 * CGRectGetHeight(self.bounds))];
[_textLabel[0] setText:[_scrollingTextArray objectAtIndex:_index]];
}
else
{
[_textLabel[1] setFrame:CGRectOffset(_textLabel[1].frame, 0.0, -2 * CGRectGetHeight(self.bounds))];
[_textLabel[1] setText:[_scrollingTextArray objectAtIndex:_index]];
}
}
break;
case ScrollDirectionFromBottomToTop:
{
if(_textLabel[0].frame.origin.y <= -CGRectGetHeight(self.bounds))
{
[_textLabel[0] setFrame:CGRectOffset(_textLabel[0].frame, 0.0, 2 * CGRectGetHeight(self.bounds))];
[_textLabel[0] setText:[_scrollingTextArray objectAtIndex:_index]];
}
else
{
[_textLabel[1] setFrame:CGRectOffset(_textLabel[1].frame, 0.0, 2 * CGRectGetHeight(self.bounds))];
[_textLabel[1] setText:[_scrollingTextArray objectAtIndex:_index]];
}
}
break;
default:
break;
}
[self startAnimating];
}
}
// Init text label
- (UILabel *)textLabelWithFrame:(CGRect)frame
{
UILabel *textLabel = [[UILabel alloc] initWithFrame:frame];
[textLabel setBackgroundColor:[UIColor clearColor]];
[textLabel setFont:[UIFont systemFontOfSize:12]];
[textLabel setLineBreakMode:UILineBreakModeTailTruncation];
return textLabel;
}
@end
原文地址:http://blog.csdn.net/lixuwen521/article/details/41679189