转载

iOS之UI--辉光动画

前言:学习来自YouXianMing老师的博客:《辉光UIView的category 》以及YouXianMing老师的github源码:《  GlowView 》

而我个人考虑到分类的二次拓展性(或者是再一次拓展)不是特别好,所以将YouXianMing老师的用分类拓展的辉光动画,改写成一个继承CALayer的可拓展的普通类。

一方面,也是作为自我训练编码,对辉光UIView的实现所使用到的 上下文绘制、核心动画、GCD中的定时器以及Runtime动态添加属性 等知识进一步的熟练运用和提高。

个人经验不足,也许观点片面,读者尽量指出,我不会介意的。嘻嘻。

先展示效果图:

iOS之UI--辉光动画 源码下载地址: https://github.com/HeYang123456789/UIView

源码:

  1 //  2 //  GlowLayer.h  3 //  GlowView  4 //  5 //  Created by HEYANG on 16/1/30.  6 //  Copyright © 2016年 HeYang. All rights reserved.  7 //  8   9 #import <UIKit/UIKit.h> 10  11 //                                     == 动画时间解析 == 12 // 13 //  0.0 ----------- 0.0 ------------> glowOpacity [---------------] glowOpacity ------------> 0.0 14 //           T                T                           T                           T 15 //           |                |                           |                           | 16 //           |                |                           |                           | 17 //           .                .                           .                           . 18 //     hideDuration   animationDuration              glowDuration              animationDuration 19 // 20  21 /** 22  *  需要考虑的参数 23  *   24  *  需要考虑的逻辑 25  *      1.数值越界问题,通过懒加载 26  *      2.动画时间的安排(看前面的动画时间的解析) 27  * 28  *  需要对外公开的接口 29  */ 30  31  32 @interface GlowLayer : CALayer 33  34 #pragma mark - 对外公开的属性 35  36 #pragma mark 设置辉光效果 37 /** 辉光的阴影半径 */ 38 @property (nonatomic,strong)NSNumber *glowRadius; 39 /** 辉光的透明度 */ 40 @property (nonatomic,strong)NSNumber *glowOpacity; 41  42 #pragma mark 设置辉光的时间 43 /** 保持辉光的时间,默认设置为0.5f */ 44 @property (nonatomic,strong)NSNumber *glowDuration; 45 /** 不显示辉光的时间,默认设置为0.5f */ 46 @property (nonatomic,strong)NSNumber *hideDuration; 47 /** 辉光的变化时间,从明到暗或者是从暗到明,默认设置为1.f */ 48 @property (nonatomic,strong)NSNumber *glowAnimationDuration; 49  50  51 #pragma mark - 对外公开的接口 52  53 /** 在原始的View上创建出辉光layer */ 54 -(void)createGlowLayerWithOriginView:(UIView*)originView glowColor:(UIColor*)glowColor; 55  56 /** 显示辉光 */ 57 -(void)showGLowLayer; 58  59 /** 隐藏辉光 */ 60 -(void)hideGlowLayer; 61  62 /** 开始循环辉光动画 */ 63 -(void)startGlowAnimation; 64  65 /** 暂停辉光动画 */ 66 -(void)pauseGlowAnimation; 67  68 /** 重启辉光动画 */ 69 -(void)reStareGlowAnimation; 70  71 @end 72  73 @interface UIView (GlowViews) 74  75 /** GlowLayer */ 76 @property (nonatomic,strong)GlowLayer *glowLayer; 77  78  79 /** 创建GlowLayer,默认辉光颜色为红色 */ 80 -(void)addGlowLayer; 81 /** 创建GlowLayer,需要设置辉光颜色 */ 82 -(void)addGlowLayerWithGlowColor:(UIColor*)glowColor; 83  84 /** 插入辉光 */ 85 -(void)insertGlowLayerToSuperlayer; 86  87 /** 完全移除GLowLayer */ 88 -(void)removeGlowLayerFromSuperlayer; 89 @end 
   1 //   2 //  GlowLayer.m   3 //  GlowView   4 //   5 //  Created by HEYANG on 16/1/30.   6 //  Copyright © 2016年 HeYang. All rights reserved.   7 //   8    9 #import "GlowLayer.h"  10   11 @interface GlowLayer ()  12   13 /** 辉光的颜色 */  14 @property (nonatomic,strong)UIColor *glowColor;  15   16 /** 需要添加辉光效果的View ,注意这里用的是weak,而不是strong */  17 @property (nonatomic,weak)UIView *addedGlowView;  18   19 /** dispatch_source_t */  20 @property (nonatomic,strong)dispatch_source_t timer;  21 @end  22   23 @implementation GlowLayer  24   25 #pragma mark - 创建辉光  26   27 // 遗留了一个先后顺序的问题,  28 /** 在原始的View上创建出辉光layer */  29 -(void)createGlowLayerWithOriginView:(UIView*)originView glowColor:(UIColor*)glowColor{  30     self.glowColor = glowColor;  31     // 创建一个图形上下文 参数:CGSize size:上下文的尺寸 BOOL opaque是否不透明 CGFloat scale缩放因子  32     UIGraphicsBeginImageContextWithOptions(originView.bounds.size, NO, [UIScreen mainScreen].scale);  33     // 通过get函数得到当前图形上下文,然后将origingView上的图形渲染到这个图形上下文上  34     [originView.layer renderInContext:UIGraphicsGetCurrentContext()];  35     // 创建贝塞尔曲线  36     UIBezierPath *path = [UIBezierPath bezierPathWithRect:originView.bounds];  37     // 设置贝塞尔取消绘制的颜色  38     [self.glowColor setFill];//这里还是需要懒加载  39     // 设置贝塞尔曲线绘制模式  40     [path fillWithBlendMode:kCGBlendModeSourceAtop alpha:1];  41       42       43     // 设置self(GlowLayer)初始状态  44     self.frame = originView.bounds;  45     // 至少要在设置好当前frame值之后,然后添加图形上下文的Image  46     // 获得当前图形上下文的图形,然后赋值给CALayer的constraints  47     self.contents = (__bridge id _Nullable)(UIGraphicsGetImageFromCurrentImageContext().CGImage);  48   49     // 阴影设置不透明,其他的设置为透明  50     self.opacity = 0.f;  51     self.shadowOpacity = 1.f;  52     // 阴影偏移量为(0,0)  53     self.shadowOffset = CGSizeMake(0, 0);  54       55       56     // 关闭图形上下文  57     UIGraphicsEndImageContext();  58       59     // 强引用指向这个原来的View  60     self.addedGlowView = originView;  61 }  62   63   64   65 #pragma mark - 显示和隐藏辉光  66   67 /** 显示辉光 */  68 -(void)showGLowLayer{  69     // 设置阴影初始效果  70     self.shadowColor = self.glowColor.CGColor;  71     self.shadowRadius = self.glowRadius.floatValue;  72       73       74     CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"opacity"];  75     animation.fromValue = @(0);  76     animation.toValue = self.glowOpacity;  77     animation.duration = self.glowAnimationDuration.floatValue;  78     // 设置最终值  79     self.opacity = self.glowOpacity.floatValue;  80       81     [self addAnimation:animation forKey:nil];  82 }  83   84 /** 隐藏辉光 */  85 -(void)hideGlowLayer{  86     self.shadowColor = self.glowColor.CGColor;  87     self.shadowRadius = self.glowRadius.floatValue;  88       89     CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"opacity"];  90     animation.fromValue = self.glowOpacity;  91     animation.toValue = @(0);  92     animation.duration = self.glowAnimationDuration.floatValue;  93     // 设置最终值  94     self.opacity = 0;  95       96     [self addAnimation:animation forKey:nil];  97 }  98   99 #pragma mark - 循环显示和隐藏辉光 100  101 /** 开始循环辉光动画 */ 102 -(void)startGlowAnimation{ 103     CGFloat cycleTime = self.glowAnimationDuration.floatValue * 2 104     + self.glowDuration.floatValue + self.hideDuration.floatValue; 105     CGFloat delayTime = self.glowAnimationDuration.floatValue + self.glowDuration.floatValue; 106      107     _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue()); 108     dispatch_source_set_timer(_timer, DISPATCH_TIME_NOW, cycleTime * NSEC_PER_SEC, 0); 109     dispatch_source_set_event_handler(_timer, ^{ 110         [self showGLowLayer]; 111         dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayTime * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ 112             [self hideGlowLayer]; 113         }); 114     }); 115     dispatch_resume(_timer); 116 } 117 /** 暂停辉光动画 */ 118 -(void)pauseGlowAnimation{ 119     [self removeFromSuperlayer]; 120 } 121 /** 重启辉光动画 */ 122 -(void)reStareGlowAnimation{ 123     [self.addedGlowView.layer addSublayer:self]; 124     [self startGlowAnimation]; 125 } 126  127 #pragma mark - 懒加载辉光的效果,同时处理数据越界问题 128 #pragma mark duration 辉光时间 129 -(NSNumber *)glowDuration{ 130     if (!_glowDuration || _glowDuration.floatValue < 0) { 131         _glowDuration = @(0.5f); 132     } 133     return _glowDuration; 134 } 135 -(NSNumber *)hideDuration{ 136     if (!_hideDuration || _hideDuration.floatValue < 0) { 137         _hideDuration = @(0.5); 138     } 139     return _hideDuration; 140 } 141 -(NSNumber *)glowAnimationDuration{ 142     if (!_glowDuration || _glowDuration.floatValue < 0) { 143         _glowDuration = @(1.f); 144     } 145     return _glowDuration; 146 } 147 #pragma mark 辉光颜色 148 -(UIColor *)glowColor{ 149     if (!_glowColor) { 150         _glowColor = [UIColor redColor]; 151     } 152     return _glowColor; 153 } 154 #pragma mark 辉光半径 155 -(NSNumber *)glowRadius{ 156     if (!_glowRadius || _glowRadius.floatValue <= 0) { 157         _glowRadius = @(2.f); 158     } 159     return _glowRadius; 160 } 161 #pragma mark 辉光透明度 162 -(NSNumber *)glowOpacity{ 163     if (!_glowOpacity || _glowOpacity.floatValue <= 0) { 164         _glowOpacity = @(0.8); 165     } 166     return _glowOpacity; 167 } 168 @end 169  170 #import <objc/runtime.h> 171  172 @implementation UIView (GlowViews) 173  174 /** 创建GlowLayer,默认辉光颜色为红色 */ 175 -(void)addGlowLayer{ 176     [self addGlowLayerWithGlowColor:nil]; 177 } 178 /** 创建GlowLayer,需要设置辉光颜色 */ 179 -(void)addGlowLayerWithGlowColor:(UIColor*)glowColor{ 180     if (self.glowLayer == nil) { 181         self.glowLayer = [[GlowLayer alloc] init]; 182     } 183     [self.glowLayer createGlowLayerWithOriginView:self glowColor:glowColor]; 184     [self insertGlowLayerToSuperlayer]; 185 } 186 #pragma mark - 插入和移除辉光 187  188 /** 插入辉光 */ 189 -(void)insertGlowLayerToSuperlayer{ 190     if (self.glowLayer == nil) { 191         self.glowLayer = [[GlowLayer alloc] init]; 192     } 193     [self.layer addSublayer:self.glowLayer]; 194 } 195  196  197 /** 移除辉光 */ 198 -(void)removeGlowLayerFromSuperlayer{ 199     [self.glowLayer removeFromSuperlayer]; 200     self.glowLayer = nil; 201 } 202  203 #pragma mark - Runtime动态添加属性 204 NSString * const _recognizerGlowLayer = @"_recognizerGlowLayer"; 205 -(void)setGlowLayer:(GlowLayer *)glowLayer{ 206     objc_setAssociatedObject(self, (__bridge const void *)(_recognizerGlowLayer), glowLayer, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 207 } 208 -(GlowLayer *)glowLayer{ 209     return objc_getAssociatedObject(self, (__bridge const void *)(_recognizerGlowLayer)); 210 } 211  212  213 @end 

使用实例:

iOS之UI--辉光动画

转载注明出处:http://www.cnblogs.com/goodboy-heyang/p/5172807.html,尊重劳动成果哦。

原文  http://www.cnblogs.com/goodboy-heyang/p/5172807.html
正文到此结束
Loading...