iOS 字體滾動效果 ScrollLabel

寫了一個簡單的字體滾動效果。html

用了一種取巧的方式,傳入兩個一摸同樣的Label(固然也能夠是別的視圖), 話很少說,代碼裏面講解。ios

SEScrollLabel.h數組

#import <UIKit/UIKit.h>ide

/*! @brief 回調代碼塊oop

 *字體

 * 當滾動效果持續loopsDone次以後,isFinished值會變爲YES,執行代碼塊動畫

 * @param loopsDone 滾動效果執行次數atom

 * @param isFinished 是否已經結束spa

 */rest

typedef void (^PMAnimationFinished)(NSUInteger loopsDone, BOOL isFinished);

enum {

    PMScrollDirectionFromLeft                   = 0,    // Animation starts from left and continues to the right side

    PMScrollDirectionFromRight                  = 1     // Animation starts from right and continues back to the left side

}; typedef NSUInteger PMScrollDirection;

 

@interface SEScrollLabel : UIScrollView

/*!

 *

 * @param frame 滾動視圖的frame

 * @param labels 存放UILabel數組,這個demo目前最多支持兩個

 * @param scrollDirection 滾動方向

 * @param scrollSpeed 滾動速度,單位是 CGFloat/s

 * @param loops 滾動執行次數

 * @param completition 執行結束調用方法

 * @return 返回SEScrollLabel對象

 */

-(instancetype)initWithFrame:(CGRect) frame labels:(NSArray *)labels

                        direction:(PMScrollDirection) scrollDirection

                        speed:(CGFloat) scrollSpeed

                        loops:(NSUInteger) loops

                completition:(PMAnimationFinished) completition;

-(void)setText:(NSString *)text;

- (void) beginAnimation;

-(void)resetAnimation;

@end

 

SEScrollLabel.m

#import "SEScrollLabel.h"

#define LABEL_SPACING 30   //定義了字體滾動的間隙

@interface SEScrollLabel()

 

@property (nonatomic, assign) BOOL needAnimating; //是否須要滾動,label長度大於scrollLabel長度,設爲YES,不然爲NO

@property (nonatomic, assign) BOOL isAnimating;      //是否正在滾動

@property (nonatomic, assign) CGFloat scrollSpeed;   //滾動速度

 

@property (nonatomic, assign) NSInteger numberOfLoops; //滾動循環次數

@property (nonatomic, assign) NSInteger runningLoops;   //當前已經執行過的滾動次數

 

@property (nonatomic, assign) PMScrollDirection scrollDirection;  //滾動方向

@property (nonatomic, strong) PMAnimationFinished finishedBlock; //回調代碼塊

@end

 

@implementation SEScrollLabel

 

-(instancetype)initWithFrame:(CGRect) frame labels:(NSArray *)labels

                        direction:(PMScrollDirection) scrollDirection

                        speed:(CGFloat) scrollSpeed

                        loops:(NSUInteger) loops

                        completition:(PMAnimationFinished) completition

{

    self = [super initWithFrame:frame];

    if (self != nil)

    {

        UILabel *label = [labels firstObject];

        CGRect labelFrame = label.frame;

        if (label.frame.size.width <= frame.size.width) //若是第一個label寬度小於視圖寬度,則判斷不須要滾動顯示

        {

            self.contentSize = CGSizeMake(labelFrame.size.width , labelFrame.size.height);

            labelFrame.origin.x = frame.size.width - labelFrame.size.width;

            labelFrame.origin.y = 0;

            label.frame = labelFrame;

            [self addSubview:label];

            _needAnimating = NO;

        }

        else

        {

            self.contentSize = CGSizeMake(labelFrame.size.width *2 + LABEL_SPACING *2 , labelFrame.size.height);

            labelFrame.origin.x = 0;

            labelFrame.origin.y = 0;

            label.frame = labelFrame;

            [self addSubview:label];

            

            if (scrollDirection == PMScrollDirectionFromRight)

            {

                labelFrame.origin.x += LABEL_SPACING + labelFrame.size.width;

            }

            else if (scrollDirection == PMScrollDirectionFromLeft)

            {

                labelFrame.origin.x -= LABEL_SPACING + labelFrame.size.width;

            }

            

            UILabel *sameLabel = [labels lastObject];

            sameLabel.frame = labelFrame;

            [self addSubview:sameLabel];

            self.scrollDirection = scrollDirection;

            self.scrollSpeed = scrollSpeed;

            self.numberOfLoops = loops;

            self.finishedBlock = completition;

            self.needAnimating = YES;

        }

    }

    return self;

}

 

- (void) beginAnimation  

{

  //所作的動畫很是簡單,就是讓scrollView的conentOffset從0開始到contentSize.width/2的距離內不斷循環,這裏須要注意contentSize是怎麼設置才能達到想要的效果

    if (!self.needAnimating) return;

    if (self.isAnimating) return;

    [self setContentOffset:CGPointZero];

 

    self.isAnimating = YES;

    

    NSTimeInterval animationDuration = (self.contentSize.width/self.scrollSpeed);

    [UIView animateWithDuration:animationDuration

                          delay:0

                        options:UIViewAnimationOptionCurveLinear

                     animations:^{

                         CGPoint finalPoint = CGPointZero;

                         if (self.scrollDirection == PMScrollDirectionFromRight)

                             finalPoint = CGPointMake(self.contentSize.width/2, 0);

                         else if (self.scrollDirection == PMScrollDirectionFromLeft)

                             finalPoint = CGPointMake(-self.contentSize.width/2, 0);

                         self.contentOffset = finalPoint;

                     } completion:^(BOOL finished) {

                         if (finished) {

                             self.isAnimating = NO;

                             

                             BOOL restartAnimation = (self.numberOfLoops == 0 || self.runningLoops <= self.numberOfLoops);

                             if (self.finishedBlock)

                             {

                                 self.finishedBlock((self.runningLoops+1),!restartAnimation);

                             }

                             

                             if (restartAnimation)

                                 [self beginAnimation];

                             else

                                 [self endAnimation:NO];

                             

                             self.runningLoops++;

                         }

                     }];

}

 

-(void)resetAnimation

{

//重置循環,將計數變爲0,而後從新開始滾動

    self.isAnimating = NO;

    self.runningLoops = 0;

    [self beginAnimation];

}

 

- (void) endAnimation:(BOOL) animated {

    if (!self.isAnimating) return;

    self.isAnimating = NO;

    [self setContentOffset:CGPointZero animated:NO];

}

 

-(void)setText:(NSString *)text

{

//改變文字,這裏我偷了個懶,沒有從新去修改contentSize和label的frame, 因此運行效果可能有些問題,根據本身想要的效果進行修改吧

    for (UIView *view in self.subviews)

    {

        if ([view isKindOfClass:[UILabel class]])

        {

            [(UILabel *)view setText:text];

        }

    }

}

@end

 

用法實例:

    SEScrollLabel *scrollLabel = [[SEScrollLabel alloc] initWithFrame:CGRectMake(0, 0, 80, 30) labels:@[label, sameLabel] direction:PMScrollDirectionFromRight speed:15 loops:3 completition:^(NSUInteger loopsDone, BOOL isFinished) {

NSLog(@"已經運行了%ld次,循環%@結束", (unsigned long)loopsDone, isFinished ? @"已經": @"還沒有");

    }];

    [self.view addSubview:scrollLabel];

    [scrollLabel beginAnimation];

 

附上效果圖一枚:

 

 

具體源碼請訪問 http://www.cnblogs.com/sely-ios/p/4552134.html

相關文章
相關標籤/搜索