zoukankan      html  css  js  c++  java
  • 带辉光效果的跑马灯

    带辉光效果的跑马灯

    效果

    说明

    并没有对代码进行封装,以后会在项目 Animationhttps://github.com/YouXianMing/Animations)里面进行集成,欢迎前去star。

    源码

    UIView+GlowView

    //
    //  UIView+GlowView.h
    //  GlowView
    //
    //  Created by YouXianMing on 15/7/4.
    //  Copyright (c) 2015年 YouXianMing. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    @interface UIView (GlowView)
    
    //
    //                                     == 动画时间解析 ==
    //
    //  0.0 ------------- 0.0 ------------> glowOpacity [-------------] glowOpacity ------------> 0.0
    //           T                 T                           T                          T
    //           |                 |                           |                          |
    //           |                 |                           |                          |
    //           .                 .                           .                          .
    //     hideDuration  glowAnimationDuration           glowDuration            glowAnimationDuration
    //
    
    #pragma mark - 设置辉光效果
    
    /**
     *  辉光的颜色
     */
    @property (nonatomic, strong) UIColor  *glowColor;
    
    /**
     *  辉光的透明度
     */
    @property (nonatomic, strong) NSNumber *glowOpacity;
    
    /**
     *  辉光的阴影半径
     */
    @property (nonatomic, strong) NSNumber *glowRadius;
    
    #pragma mark - 设置辉光时间间隔
    
    /**
     *  一次完整的辉光周期(从显示到透明或者从透明到显示),默认1s
     */
    @property (nonatomic, strong) NSNumber *glowAnimationDuration;
    
    /**
     *  保持辉光时间(不设置,默认为0.5s)
     */
    @property (nonatomic, strong) NSNumber *glowDuration;
    
    /**
     *  不显示辉光的周期(不设置默认为0.5s)
     */
    @property (nonatomic, strong) NSNumber *hideDuration;
    
    #pragma mark - 辉光相关操作
    
    /**
     *  创建出辉光layer
     */
    - (void)createGlowLayer;
    
    /**
     *  插入辉光的layer
     */
    - (void)insertGlowLayer;
    
    /**
     *  移除辉光的layer
     */
    - (void)removeGlowLayer;
    
    /**
     *  显示辉光
     */
    - (void)glowToshow;
    
    /**
     *  隐藏辉光
     */
    - (void)glowToHide;
    
    /**
     *  开始循环辉光
     */
    - (void)startGlowLoop;
    
    @end
    UIView+GlowView.h
    //
    //  UIView+GlowView.m
    //  GlowView
    //
    //  Created by YouXianMing on 15/7/4.
    //  Copyright (c) 2015年 YouXianMing. All rights reserved.
    //
    
    #import "UIView+GlowView.h"
    #import <objc/runtime.h>
    
    @interface UIView ()
    
    @property (nonatomic, strong) CALayer           *glowLayer;
    @property (nonatomic, strong) dispatch_source_t  dispatchSource;
    
    @end
    
    @implementation UIView (GlowView)
    
    - (void)createGlowLayer {
        
        UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, [UIScreen mainScreen].scale);
        [self.layer renderInContext:UIGraphicsGetCurrentContext()];
        UIBezierPath* path = [UIBezierPath bezierPathWithRect:self.bounds];
        [[self accessGlowColor] setFill];
        [path fillWithBlendMode:kCGBlendModeSourceAtop alpha:1.0];
        
        self.glowLayer               = [CALayer layer];
        self.glowLayer.frame         = self.bounds;
        self.glowLayer.contents      = (__bridge id)UIGraphicsGetImageFromCurrentImageContext().CGImage;
        self.glowLayer.opacity       = 0.f;
        self.glowLayer.shadowOffset  = CGSizeMake(0, 0);
        self.glowLayer.shadowOpacity = 1.f;
        
        UIGraphicsEndImageContext();
    }
    
    - (void)insertGlowLayer {
        
        if (self.glowLayer) {
            
            [self.layer addSublayer:self.glowLayer];
        }
    }
    
    - (void)removeGlowLayer {
        
        if (self.glowLayer) {
            
            [self.glowLayer removeFromSuperlayer];
        }
    }
    
    - (void)glowToshow {
        
        self.glowLayer.shadowColor   = [self accessGlowColor].CGColor;
        self.glowLayer.shadowRadius  = [self accessGlowRadius].floatValue;
        
        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
        animation.fromValue         = @(0.f);
        animation.toValue           = [self accessGlowOpacity];
        self.glowLayer.opacity      = [self accessGlowOpacity].floatValue;
        animation.duration          = [self accessAnimationDuration].floatValue;
        
        [self.glowLayer addAnimation:animation forKey:nil];
    }
    
    - (void)glowToHide {
        
        self.glowLayer.shadowColor   = [self accessGlowColor].CGColor;
        self.glowLayer.shadowRadius  = [self accessGlowRadius].floatValue;
        
        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
        animation.fromValue         = [self accessGlowOpacity];
        animation.toValue           = @(0.f);
        self.glowLayer.opacity      = 0.f;
        animation.duration          = [self accessAnimationDuration].floatValue;
        
        [self.glowLayer addAnimation:animation forKey:nil];
    }
    
    - (void)startGlowLoop {
        
        if (self.dispatchSource == nil) {
            
            CGFloat seconds      = [self accessAnimationDuration].floatValue * 2 + [self accessGlowDuration].floatValue + [self accessHideDuration].floatValue;
            CGFloat delaySeconds = [self accessAnimationDuration].floatValue + [self accessGlowDuration].floatValue;
            
            self.dispatchSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
            dispatch_source_set_timer(self.dispatchSource, dispatch_time(DISPATCH_TIME_NOW, 0), NSEC_PER_SEC * seconds, 0);
            dispatch_source_set_event_handler(self.dispatchSource, ^{
                
                [self glowToshow];
                
                dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * delaySeconds), dispatch_get_main_queue(), ^{
                    
                    [self glowToHide];
                });
            });
            
            dispatch_resume(self.dispatchSource);
        }
    }
    
    #pragma mark - 处理数据越界问题
    
    - (NSNumber *)accessGlowOpacity {
        
        if (self.glowOpacity) {
            
            if (self.glowOpacity.floatValue <= 0 || self.glowOpacity.floatValue > 1) {
                
                return @(0.8);
                
            } else {
                
                return self.glowOpacity;
            }
            
        } else {
            
            return @(0.8);
        }
    }
    
    - (NSNumber *)accessGlowDuration {
        
        if (self.glowDuration) {
            
            if (self.glowDuration.floatValue <= 0) {
                
                return @(0.5f);
                
            } else {
                
                return self.glowDuration;
            }
            
        } else {
            
            return @(0.5f);
        }
    }
    
    - (NSNumber *)accessHideDuration {
        
        if (self.hideDuration) {
            
            if (self.hideDuration.floatValue < 0) {
                
                return @(0.5);
                
            } else {
                
                return self.hideDuration;
            }
            
        } else {
            
            return @(0.5f);
        }
    }
    
    - (NSNumber *)accessAnimationDuration {
        
        if (self.glowAnimationDuration) {
            
            if (self.glowAnimationDuration.floatValue <= 0) {
                
                return @(1.f);
                
            } else {
                
                return self.glowAnimationDuration;
            }
            
        } else {
            
            return @(1.f);
        }
    }
    
    - (UIColor *)accessGlowColor {
        
        if (self.glowColor) {
            
            return self.glowColor;
            
        } else {
            
            return [UIColor redColor];
        }
    }
    
    - (NSNumber *)accessGlowRadius {
        
        if (self.glowRadius) {
            
            if (self.glowRadius.floatValue <= 0) {
                
                return @(2.f);
                
            } else {
                
                return self.glowRadius;
            }
            
        } else {
            
            return @(2.f);
        }
    }
    
    #pragma mark - runtime属性
    
    NSString * const _recognizerDispatchSource = @"_recognizerDispatchSource";
    
    - (void)setDispatchSource:(dispatch_source_t)dispatchSource {
        
        objc_setAssociatedObject(self, (__bridge const void *)(_recognizerDispatchSource), dispatchSource, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (dispatch_source_t)dispatchSource {
        
        return objc_getAssociatedObject(self, (__bridge const void *)(_recognizerDispatchSource));
    }
    
    NSString * const _recognizerGlowColor = @"_recognizerGlowColor";
    
    - (void)setGlowColor:(UIColor *)glowColor {
        
        objc_setAssociatedObject(self, (__bridge const void *)(_recognizerGlowColor), glowColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (UIColor *)glowColor {
        
        return objc_getAssociatedObject(self, (__bridge const void *)(_recognizerGlowColor));
    }
    
    NSString * const _recognizerGlowOpacity = @"_recognizerGlowOpacity";
    
    - (void)setGlowOpacity:(NSNumber *)glowOpacity {
        
        objc_setAssociatedObject(self, (__bridge const void *)(_recognizerGlowOpacity), glowOpacity, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (NSNumber *)glowOpacity {
        
        return objc_getAssociatedObject(self, (__bridge const void *)(_recognizerGlowOpacity));
    }
    
    NSString * const _recognizerGlowRadius = @"_recognizerGlowRadius";
    
    - (void)setGlowRadius:(NSNumber *)glowRadius {
        
        objc_setAssociatedObject(self, (__bridge const void *)(_recognizerGlowRadius), glowRadius, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (NSNumber *)glowRadius {
        
        return objc_getAssociatedObject(self, (__bridge const void *)(_recognizerGlowRadius));
    }
    
    NSString * const _recognizerGlowAnimationDuration = @"_recognizerGlowAnimationDuration";
    
    - (void)setGlowAnimationDuration:(NSNumber *)glowAnimationDuration {
        
        objc_setAssociatedObject(self, (__bridge const void *)(glowAnimationDuration), _recognizerGlowAnimationDuration, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (NSNumber *)glowAnimationDuration {
        
        return objc_getAssociatedObject(self, (__bridge const void *)(_recognizerGlowAnimationDuration));
    }
    
    NSString * const _recognizerGlowDuration = @"_recognizerGlowDuration";
    
    - (void)setGlowDuration:(NSNumber *)glowDuration {
        
        objc_setAssociatedObject(self, (__bridge const void *)(_recognizerGlowDuration), glowDuration, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (NSNumber *)glowDuration {
        
        return objc_getAssociatedObject(self, (__bridge const void *)(_recognizerGlowDuration));
    }
    
    NSString * const _recognizerHideDuration = @"_recognizerHideDuration";
    
    - (void)setHideDuration:(NSNumber *)hideDuration {
        
        objc_setAssociatedObject(self, (__bridge const void *)(_recognizerHideDuration), hideDuration, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (NSNumber *)hideDuration {
        
        return objc_getAssociatedObject(self, (__bridge const void *)(_recognizerHideDuration));
    }
    
    NSString * const _recognizerGlowLayer = @"_recognizerGlowLayer";
    
    - (void)setGlowLayer:(CALayer *)glowLayer {
        
        objc_setAssociatedObject(self, (__bridge const void *)(_recognizerGlowLayer), glowLayer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    }
    
    - (CALayer *)glowLayer {
        
        return objc_getAssociatedObject(self, (__bridge const void *)(_recognizerGlowLayer));
    }
    
    @end
    UIView+GlowView.m

    UIView+SetRect

    //
    //  UIView+SetRect.h
    //  UIView
    //
    //  Created by YouXianMing on 16/1/29.
    //  Copyright © 2016年 YouXianMing. All rights reserved.
    //
    
    #import <UIKit/UIKit.h>
    
    /**
     *  UIScreen width.
     */
    #define  Width   [UIScreen mainScreen].bounds.size.width
    
    /**
     *  UIScreen height.
     */
    #define  Height  [UIScreen mainScreen].bounds.size.height
    
    /**
     *  Status bar height.
     */
    #define  StatusBarHeight      20.f
    
    /**
     *  Navigation bar height.
     */
    #define  NavigationBarHeight  44.f
    
    /**
     *  Tabbar height.
     */
    #define  TabbarHeight         49.f
    
    /**
     *  Status bar & navigation bar height.
     */
    #define  StatusBarAndNavigationBarHeight   (20.f + 44.f)
    
    /**
     *  iPhone4 or iPhone4s
     */
    #define  iPhone4_4s     (Width == 320.f && Height == 480.f ? YES : NO)
    
    /**
     *  iPhone5 or iPhone5s
     */
    #define  iPhone5_5s     (Width == 320.f && Height == 568.f ? YES : NO)
    
    /**
     *  iPhone6 or iPhone6s
     */
    #define  iPhone6_6s     (Width == 375.f && Height == 667.f ? YES : NO)
    
    /**
     *  iPhone6Plus or iPhone6sPlus
     */
    #define  iPhone6_6sPlus (Width == 414.f && Height == 736.f ? YES : NO)
    
    @interface UIView (SetRect)
    
    /*----------------------
     * Absolute coordinate *
     ----------------------*/
    
    @property (nonatomic) CGPoint viewOrigin;
    @property (nonatomic) CGSize  viewSize;
    
    @property (nonatomic) CGFloat x;
    @property (nonatomic) CGFloat y;
    @property (nonatomic) CGFloat width;
    @property (nonatomic) CGFloat height;
    
    @property (nonatomic) CGFloat top;
    @property (nonatomic) CGFloat bottom;
    @property (nonatomic) CGFloat left;
    @property (nonatomic) CGFloat right;
    
    @property (nonatomic) CGFloat centerX;
    @property (nonatomic) CGFloat centerY;
    
    /*----------------------
     * Relative coordinate *
     ----------------------*/
    
    @property (nonatomic, readonly) CGFloat middleX;
    @property (nonatomic, readonly) CGFloat middleY;
    @property (nonatomic, readonly) CGPoint middlePoint;
    
    @end
    UIView+SetRect.h
    //
    //  UIView+SetRect.m
    //  UIView
    //
    //  Created by YouXianMing on 16/1/29.
    //  Copyright © 2016年 YouXianMing. All rights reserved.
    //
    
    #import "UIView+SetRect.h"
    
    @implementation UIView (SetRect)
    
    - (CGPoint)viewOrigin {
        
        return self.frame.origin;
    }
    
    - (void)setViewOrigin:(CGPoint)viewOrigin {
        
        CGRect newFrame = self.frame;
        newFrame.origin = viewOrigin;
        self.frame      = newFrame;
    }
    
    - (CGSize)viewSize {
        
        return self.frame.size;
    }
    
    - (void)setViewSize:(CGSize)viewSize {
        
        CGRect newFrame = self.frame;
        newFrame.size   = viewSize;
        self.frame      = newFrame;
    }
    
    - (CGFloat)x {
        
        return self.frame.origin.x;
    }
    
    - (void)setX:(CGFloat)x {
        
        CGRect newFrame   = self.frame;
        newFrame.origin.x = x;
        self.frame        = newFrame;
    }
    
    - (CGFloat)y {
        
        return self.frame.origin.y;
    }
    
    - (void)setY:(CGFloat)y {
        
        CGRect newFrame   = self.frame;
        newFrame.origin.y = y;
        self.frame        = newFrame;
    }
    
    - (CGFloat)width {
        
        return CGRectGetWidth(self.bounds);
    }
    
    - (void)setWidth:(CGFloat)width {
        
        CGRect newFrame     = self.frame;
        newFrame.size.width = width;
        self.frame          = newFrame;
    }
    
    - (CGFloat)height {
        
        return CGRectGetHeight(self.bounds);
    }
    
    - (void)setHeight:(CGFloat)height {
        
        CGRect newFrame      = self.frame;
        newFrame.size.height = height;
        self.frame           = newFrame;
    }
    
    - (CGFloat)top {
        
        return self.frame.origin.y;
    }
    
    - (void)setTop:(CGFloat)top {
        
        CGRect newFrame   = self.frame;
        newFrame.origin.y = top;
        self.frame        = newFrame;
    }
    
    - (CGFloat)bottom {
        
        return self.frame.origin.y + self.frame.size.height;
    }
    
    - (void)setBottom:(CGFloat)bottom {
        
        CGRect newFrame   = self.frame;
        newFrame.origin.y = bottom - self.frame.size.height;
        self.frame        = newFrame;
    }
    
    - (CGFloat)left {
        
        return self.frame.origin.x;
    }
    
    - (void)setLeft:(CGFloat)left {
        
        CGRect newFrame   = self.frame;
        newFrame.origin.x = left;
        self.frame        = newFrame;
    }
    
    - (CGFloat)right {
        
        return self.frame.origin.x + self.frame.size.width;
    }
    
    - (void)setRight:(CGFloat)right {
        
        CGRect newFrame   = self.frame;
        newFrame.origin.x = right - self.frame.size.width;
        self.frame        = newFrame;
    }
    
    - (CGFloat)centerX {
        
        return self.center.x;
    }
    
    - (void)setCenterX:(CGFloat)centerX {
        
        CGPoint newCenter = self.center;
        newCenter.x       = centerX;
        self.center       = newCenter;
    }
    
    - (CGFloat)centerY {
        
        return self.center.y;
    }
    
    - (void)setCenterY:(CGFloat)centerY {
        
        CGPoint newCenter = self.center;
        newCenter.y       = centerY;
        self.center       = newCenter;
    }
    
    - (CGFloat)middleX {
        
        return CGRectGetWidth(self.bounds) / 2.f;
    }
    
    - (CGFloat)middleY {
        
        return CGRectGetHeight(self.bounds) / 2.f;
    }
    
    - (CGPoint)middlePoint {
        
        return CGPointMake(CGRectGetWidth(self.bounds) / 2.f, CGRectGetHeight(self.bounds) / 2.f);
    }
    
    @end
    UIView+SetRect.m

    NSString+LabelWidthAndHeight

    //
    //  NSString+LabelWidthAndHeight.h
    //  ZiPeiYi
    //
    //  Created by YouXianMing on 15/12/9.
    //  Copyright © 2015年 YouXianMing. All rights reserved.
    //
    
    #import <Foundation/Foundation.h>
    #import <UIKit/UIKit.h>
    
    @interface NSString (LabelWidthAndHeight)
    
    /**
     *  Get the string's height with the fixed width.
     *
     *  @param attribute String's attribute, eg. attribute = @{NSFontAttributeName: [UIFont systemFontOfSize:18.f]}
     *  @param width     Fixed width.
     *
     *  @return String's height.
     */
    - (CGFloat)heightWithStringAttribute:(NSDictionary <NSString *, id> *)attribute fixedWidth:(CGFloat)width;
    
    /**
     *  Get the string's width.
     *
     *  @param attribute String's attribute, eg. attribute = @{NSFontAttributeName: [UIFont systemFontOfSize:18.f]}
     *
     *  @return String's width.
     */
    - (CGFloat)widthWithStringAttribute:(NSDictionary <NSString *, id> *)attribute;
    
    /**
     *  Get a line of text height.
     *
     *  @param attribute String's attribute, eg. attribute = @{NSFontAttributeName: [UIFont systemFontOfSize:18.f]}
     *
     *  @return String's width.
     */
    + (CGFloat)aLineOfTextHeightWithStringAttribute:(NSDictionary <NSString *, id> *)attribute;
    
    @end
    NSString+LabelWidthAndHeight.h
    //
    //  NSString+LabelWidthAndHeight.m
    //  ZiPeiYi
    //
    //  Created by YouXianMing on 15/12/9.
    //  Copyright © 2015年 YouXianMing. All rights reserved.
    //
    
    #import "NSString+LabelWidthAndHeight.h"
    
    @implementation NSString (LabelWidthAndHeight)
    
    - (CGFloat)heightWithStringAttribute:(NSDictionary <NSString *, id> *)attribute fixedWidth:(CGFloat)width {
        
        NSParameterAssert(attribute);
        
        CGFloat height = 0;
        
        if (self.length) {
            
            CGRect rect = [self boundingRectWithSize:CGSizeMake(width, MAXFLOAT)
                                             options:NSStringDrawingTruncatesLastVisibleLine |NSStringDrawingUsesLineFragmentOrigin |
                           NSStringDrawingUsesFontLeading
                                          attributes:attribute
                                             context:nil];
            
            height = rect.size.height;
        }
        
        return height;
    }
    
    - (CGFloat)widthWithStringAttribute:(NSDictionary <NSString *, id> *)attribute {
        
        NSParameterAssert(attribute);
        
        CGFloat width = 0;
        
        if (self.length) {
            
            CGRect rect = [self boundingRectWithSize:CGSizeMake(MAXFLOAT, 0)
                                             options:NSStringDrawingTruncatesLastVisibleLine |NSStringDrawingUsesLineFragmentOrigin |
                           NSStringDrawingUsesFontLeading
                                          attributes:attribute
                                             context:nil];
            
            width = rect.size.width;
        }
        
        return width;
    }
    
    + (CGFloat)aLineOfTextHeightWithStringAttribute:(NSDictionary <NSString *, id> *)attribute {
        
        CGFloat height = 0;
        CGRect rect    = [@"One" boundingRectWithSize:CGSizeMake(200, MAXFLOAT)
                                              options:NSStringDrawingTruncatesLastVisibleLine |NSStringDrawingUsesLineFragmentOrigin |
                          NSStringDrawingUsesFontLeading
                                           attributes:attribute
                                              context:nil];
        
        height = rect.size.height;
        return height;
    }
    
    @end
    NSString+LabelWidthAndHeight.m

    ViewController.m

    //
    //  ViewController.m
    //  UILabel
    //
    //  Created by YouXianMing on 16/4/13.
    //  Copyright © 2016年 YouXianMing. All rights reserved.
    //
    
    #import "ViewController.h"
    #import "UIView+SetRect.h"
    #import "UIView+GlowView.h"
    #import "NSString+LabelWidthAndHeight.h"
    
    @interface ViewController () <UIGestureRecognizerDelegate>
    
    @property (nonatomic, strong) UIView  *contentView;
    @property (nonatomic, strong) UILabel *label;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        
        [super viewDidLoad];
        
        self.contentView                   = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 250.f, 20)];
        self.contentView.layer.borderWidth = 0.5f;
        self.contentView.layer.masksToBounds = YES;
        self.contentView.layer.borderColor = [[UIColor grayColor] colorWithAlphaComponent:0.25f].CGColor;
        self.contentView.center            = self.view.center;
        [self.view addSubview:self.contentView];
        
        NSString *string = @"Copyright © 2016 YouXianMing. All rights reserved.";
        CGFloat   width  = [string widthWithStringAttribute:@{NSFontAttributeName : [UIFont fontWithName:@"Heiti SC" size:14.f]}];
        self.label       = [[UILabel alloc] initWithFrame:CGRectMake(self.contentView.width, 0, width, self.contentView.height)];
        self.label.font  = [UIFont fontWithName:@"Heiti SC" size:14.f];
        self.label.text  = string;
        [self.contentView addSubview:self.label];
        
        [self doAnimation];
        
        // Start glow.
        self.label.glowRadius            = @(1.f);
        self.label.glowOpacity           = @(1.f);
        self.label.glowColor             = [[UIColor cyanColor] colorWithAlphaComponent:0.5f];
        self.label.glowDuration          = @(1.f);
        self.label.hideDuration          = @(3.f);
        self.label.glowAnimationDuration = @(2.f);
        [self.label createGlowLayer];
        [self.label insertGlowLayer];
        [self.label startGlowLoop];
        
        UIPanGestureRecognizer *tapGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureEvent:)];
        tapGesture.delegate                = self;
        [self.contentView addGestureRecognizer:tapGesture];
    }
    
    - (void)doAnimation {
        
        CGPoint       fromPoint = CGPointMake(self.contentView.width + self.label.width / 2.f, self.contentView.height / 2.f);
        UIBezierPath *movePath  = [UIBezierPath bezierPath];
        [movePath moveToPoint:fromPoint];
        [movePath addLineToPoint:CGPointMake(-self.label.width / 2, self.contentView.height / 2.f)];
        
        CAKeyframeAnimation *moveAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
        moveAnimation.path                 = movePath.CGPath;
        moveAnimation.removedOnCompletion  = YES;
        moveAnimation.duration             = 8.f;
        moveAnimation.delegate             = self;
        [self.label.layer addAnimation:moveAnimation forKey:nil];
    }
    
    - (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
        
        if (flag) {
            
            [self doAnimation];
        }
    }
    
    - (void)pauseLayer:(CALayer*)layer {
        
        CFTimeInterval pausedTime = [layer convertTime:CACurrentMediaTime() fromLayer:nil];
        layer.speed               = 0.0;
        layer.timeOffset          = pausedTime;
    }
    
    - (void)resumeLayer:(CALayer*)layer {
        
        CFTimeInterval pausedTime     = layer.timeOffset;
        layer.speed                   = 1.0;
        layer.timeOffset              = 0.0;
        layer.beginTime               = 0.0;
        CFTimeInterval timeSincePause = [layer convertTime:CACurrentMediaTime() fromLayer:nil] - pausedTime;
        layer.beginTime               = timeSincePause;
    }
    
    - (void)tapGestureEvent:(UIPanGestureRecognizer *)tapGesture {
        
        if (tapGesture.state == UIGestureRecognizerStateBegan) {
            
            NSLog(@"拖拽");
            [self pauseLayer:self.label.layer];
            
        } else if (tapGesture.state == UIGestureRecognizerStateEnded) {
            
            NSLog(@"释放");
            [self resumeLayer:self.label.layer];
        }
    }
    
    @end

    细节

    暂停CALayer的动画以及恢复CALayer的动画

    用了贝塞尔曲线的Path动画来实现重复移动的效果

  • 相关阅读:
    这一段
    转安装vs2003 提示重启
    转解决VSS中Access to file "rights.dat" denied的错误
    C# 页面基类
    C#密码加密
    转 如何改变*.sln文件的路径
    后台为按钮定义js事件
    sql2005 数据库还原
    vss 代码管理器
    转 如何有效的使用C#读取文件 及如何解决中文乱码问题
  • 原文地址:https://www.cnblogs.com/YouXianMing/p/5388671.html
Copyright © 2011-2022 走看看