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

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

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

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

先展示效果图:

源码下载地址:https://github.com/HeYang123456789/UIView

源码:

 //
// GlowLayer.h
// GlowView
//
// Created by HEYANG on 16/1/30.
// Copyright © 2016年 HeYang. All rights reserved.
// #import <UIKit/UIKit.h> // == 动画时间解析 ==
//
// 0.0 ----------- 0.0 ------------> glowOpacity [---------------] glowOpacity ------------> 0.0
// T T T T
// | | | |
// | | | |
// . . . .
// hideDuration animationDuration glowDuration animationDuration
// /**
* 需要考虑的参数
*
* 需要考虑的逻辑
* 1.数值越界问题,通过懒加载
* 2.动画时间的安排(看前面的动画时间的解析)
*
* 需要对外公开的接口
*/ @interface GlowLayer : CALayer #pragma mark - 对外公开的属性 #pragma mark 设置辉光效果
/** 辉光的阴影半径 */
@property (nonatomic,strong)NSNumber *glowRadius;
/** 辉光的透明度 */
@property (nonatomic,strong)NSNumber *glowOpacity; #pragma mark 设置辉光的时间
/** 保持辉光的时间,默认设置为0.5f */
@property (nonatomic,strong)NSNumber *glowDuration;
/** 不显示辉光的时间,默认设置为0.5f */
@property (nonatomic,strong)NSNumber *hideDuration;
/** 辉光的变化时间,从明到暗或者是从暗到明,默认设置为1.f */
@property (nonatomic,strong)NSNumber *glowAnimationDuration; #pragma mark - 对外公开的接口 /** 在原始的View上创建出辉光layer */
-(void)createGlowLayerWithOriginView:(UIView*)originView glowColor:(UIColor*)glowColor; /** 显示辉光 */
-(void)showGLowLayer; /** 隐藏辉光 */
-(void)hideGlowLayer; /** 开始循环辉光动画 */
-(void)startGlowAnimation; /** 暂停辉光动画 */
-(void)pauseGlowAnimation; /** 重启辉光动画 */
-(void)reStareGlowAnimation; @end @interface UIView (GlowViews) /** GlowLayer */
@property (nonatomic,strong)GlowLayer *glowLayer; /** 创建GlowLayer,默认辉光颜色为红色 */
-(void)addGlowLayer;
/** 创建GlowLayer,需要设置辉光颜色 */
-(void)addGlowLayerWithGlowColor:(UIColor*)glowColor; /** 插入辉光 */
-(void)insertGlowLayerToSuperlayer; /** 完全移除GLowLayer */
-(void)removeGlowLayerFromSuperlayer;
@end
 //
// GlowLayer.m
// GlowView
//
// Created by HEYANG on 16/1/30.
// Copyright © 2016年 HeYang. All rights reserved.
// #import "GlowLayer.h" @interface GlowLayer () /** 辉光的颜色 */
@property (nonatomic,strong)UIColor *glowColor; /** 需要添加辉光效果的View ,注意这里用的是weak,而不是strong */
@property (nonatomic,weak)UIView *addedGlowView; /** dispatch_source_t */
@property (nonatomic,strong)dispatch_source_t timer;
@end @implementation GlowLayer #pragma mark - 创建辉光 // 遗留了一个先后顺序的问题,
/** 在原始的View上创建出辉光layer */
-(void)createGlowLayerWithOriginView:(UIView*)originView glowColor:(UIColor*)glowColor{
self.glowColor = glowColor;
// 创建一个图形上下文 参数:CGSize size:上下文的尺寸 BOOL opaque是否不透明 CGFloat scale缩放因子
UIGraphicsBeginImageContextWithOptions(originView.bounds.size, NO, [UIScreen mainScreen].scale);
// 通过get函数得到当前图形上下文,然后将origingView上的图形渲染到这个图形上下文上
[originView.layer renderInContext:UIGraphicsGetCurrentContext()];
// 创建贝塞尔曲线
UIBezierPath *path = [UIBezierPath bezierPathWithRect:originView.bounds];
// 设置贝塞尔取消绘制的颜色
[self.glowColor setFill];//这里还是需要懒加载
// 设置贝塞尔曲线绘制模式
[path fillWithBlendMode:kCGBlendModeSourceAtop alpha:]; // 设置self(GlowLayer)初始状态
self.frame = originView.bounds;
// 至少要在设置好当前frame值之后,然后添加图形上下文的Image
// 获得当前图形上下文的图形,然后赋值给CALayer的constraints
self.contents = (__bridge id _Nullable)(UIGraphicsGetImageFromCurrentImageContext().CGImage); // 阴影设置不透明,其他的设置为透明
self.opacity = .f;
self.shadowOpacity = .f;
// 阴影偏移量为(0,0)
self.shadowOffset = CGSizeMake(, ); // 关闭图形上下文
UIGraphicsEndImageContext(); // 强引用指向这个原来的View
self.addedGlowView = originView;
} #pragma mark - 显示和隐藏辉光 /** 显示辉光 */
-(void)showGLowLayer{
// 设置阴影初始效果
self.shadowColor = self.glowColor.CGColor;
self.shadowRadius = self.glowRadius.floatValue; CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
animation.fromValue = @();
animation.toValue = self.glowOpacity;
animation.duration = self.glowAnimationDuration.floatValue;
// 设置最终值
self.opacity = self.glowOpacity.floatValue; [self addAnimation:animation forKey:nil];
} /** 隐藏辉光 */
-(void)hideGlowLayer{
self.shadowColor = self.glowColor.CGColor;
self.shadowRadius = self.glowRadius.floatValue; CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
animation.fromValue = self.glowOpacity;
animation.toValue = @();
animation.duration = self.glowAnimationDuration.floatValue;
// 设置最终值
self.opacity = ; [self addAnimation:animation forKey:nil];
} #pragma mark - 循环显示和隐藏辉光 /** 开始循环辉光动画 */
-(void)startGlowAnimation{
CGFloat cycleTime = self.glowAnimationDuration.floatValue *
+ self.glowDuration.floatValue + self.hideDuration.floatValue;
CGFloat delayTime = self.glowAnimationDuration.floatValue + self.glowDuration.floatValue; _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, , , dispatch_get_main_queue());
dispatch_source_set_timer(_timer, DISPATCH_TIME_NOW, cycleTime * NSEC_PER_SEC, );
dispatch_source_set_event_handler(_timer, ^{
[self showGLowLayer];
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayTime * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[self hideGlowLayer];
});
});
dispatch_resume(_timer);
}
/** 暂停辉光动画 */
-(void)pauseGlowAnimation{
[self removeFromSuperlayer];
}
/** 重启辉光动画 */
-(void)reStareGlowAnimation{
[self.addedGlowView.layer addSublayer:self];
[self startGlowAnimation];
} #pragma mark - 懒加载辉光的效果,同时处理数据越界问题
#pragma mark duration 辉光时间
-(NSNumber *)glowDuration{
if (!_glowDuration || _glowDuration.floatValue < ) {
_glowDuration = @(0.5f);
}
return _glowDuration;
}
-(NSNumber *)hideDuration{
if (!_hideDuration || _hideDuration.floatValue < ) {
_hideDuration = @(0.5);
}
return _hideDuration;
}
-(NSNumber *)glowAnimationDuration{
if (!_glowDuration || _glowDuration.floatValue < ) {
_glowDuration = @(.f);
}
return _glowDuration;
}
#pragma mark 辉光颜色
-(UIColor *)glowColor{
if (!_glowColor) {
_glowColor = [UIColor redColor];
}
return _glowColor;
}
#pragma mark 辉光半径
-(NSNumber *)glowRadius{
if (!_glowRadius || _glowRadius.floatValue <= ) {
_glowRadius = @(.f);
}
return _glowRadius;
}
#pragma mark 辉光透明度
-(NSNumber *)glowOpacity{
if (!_glowOpacity || _glowOpacity.floatValue <= ) {
_glowOpacity = @(0.8);
}
return _glowOpacity;
}
@end #import <objc/runtime.h> @implementation UIView (GlowViews) /** 创建GlowLayer,默认辉光颜色为红色 */
-(void)addGlowLayer{
[self addGlowLayerWithGlowColor:nil];
}
/** 创建GlowLayer,需要设置辉光颜色 */
-(void)addGlowLayerWithGlowColor:(UIColor*)glowColor{
if (self.glowLayer == nil) {
self.glowLayer = [[GlowLayer alloc] init];
}
[self.glowLayer createGlowLayerWithOriginView:self glowColor:glowColor];
[self insertGlowLayerToSuperlayer];
}
#pragma mark - 插入和移除辉光 /** 插入辉光 */
-(void)insertGlowLayerToSuperlayer{
if (self.glowLayer == nil) {
self.glowLayer = [[GlowLayer alloc] init];
}
[self.layer addSublayer:self.glowLayer];
} /** 移除辉光 */
-(void)removeGlowLayerFromSuperlayer{
[self.glowLayer removeFromSuperlayer];
self.glowLayer = nil;
} #pragma mark - Runtime动态添加属性
NSString * const _recognizerGlowLayer = @"_recognizerGlowLayer";
-(void)setGlowLayer:(GlowLayer *)glowLayer{
objc_setAssociatedObject(self, (__bridge const void *)(_recognizerGlowLayer), glowLayer, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
-(GlowLayer *)glowLayer{
return objc_getAssociatedObject(self, (__bridge const void *)(_recognizerGlowLayer));
} @end

使用实例:

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

iOS之UI--辉光动画的更多相关文章

  1. iOS开发UI篇—核心动画(UIView封装动画)

    iOS开发UI篇—核心动画(UIView封装动画) 一.UIView动画(首尾) 1.简单说明 UIKit直接将动画集成到UIView类中,当内部的一些属性发生改变时,UIView将为这些改变提供动画 ...

  2. iOS开发UI篇—核心动画(转场动画和组动画)

    转自:http://www.cnblogs.com/wendingding/p/3801454.html iOS开发UI篇—核心动画(转场动画和组动画) 一.转场动画简单介绍 CAAnimation的 ...

  3. iOS开发UI篇—核心动画(关键帧动画)

    转自:http://www.cnblogs.com/wendingding/p/3801330.html iOS开发UI篇—核心动画(关键帧动画) 一.简单介绍 是CApropertyAnimatio ...

  4. iOS开发UI篇—核心动画(基础动画)

    转自:http://www.cnblogs.com/wendingding/p/3801157.html 文顶顶 最怕你一生碌碌无为 还安慰自己平凡可贵 iOS开发UI篇—核心动画(基础动画) iOS ...

  5. iOS开发UI篇—核心动画简介

    转自:http://www.cnblogs.com/wendingding/p/3801036.html iOS开发UI篇—核心动画简介 一.简单介绍 Core Animation,中文翻译为核心动画 ...

  6. Shimmer辉光动画效果

    Shimmer辉光动画效果 效果 源码 https://github.com/facebook/Shimmer https://github.com/YouXianMing/Animations // ...

  7. 使用CALayer制作View的辉光效果

    使用CALayer制作View的辉光效果 实现以下的辉光效果: 思路是这样子的: 1. 创建好需要实现辉光效果的View 2. 对这个View进行截图 3. 将这个截图重新添加进View中 4. 对这 ...

  8. iOS开发UI篇—iOS开发中三种简单的动画设置

    iOS开发UI篇—iOS开发中三种简单的动画设置 [在ios开发中,动画是廉价的] 一.首尾式动画 代码示例: // beginAnimations表示此后的代码要“参与到”动画中 [UIView b ...

  9. 辉光UIView的category

    辉光UIView的category 本人视频教程系类   iOS中CALayer的使用 效果如下: 源码: UIView+GlowView.h 与 UIView+GlowView.m // // UI ...

随机推荐

  1. 关于JavaScript中apply与call的用法意义及区别

    JavaScript中有一个call和apply方法,其作用基本相同,但也有略微的区别. 先来看看JS手册中对call的解释: call 方法调用一个对象的一个方法,以另一个对象替换当前对象. cal ...

  2. SharePoint 2013中规划企业搜索体系结构

    摘要:了解如何规划小型.中型或大型企业搜索体系结构. 设置企业搜索体系结构之前,需要仔细规划很多事项.我们将逐步帮助您规划小型.中型或大型企业搜索体系结构. 您是否熟悉 SharePoint 2013 ...

  3. Python单元测试框架之pytest -- fixtures

    fixtures不太好翻译,可看作是夹心饼干最外层的两片饼干.通常用setup/teardown来表示.它主要用来包裹测试用例,为什么需要这样的饼干呢?我们以web自动化测试为例,例如,要测试的某系统 ...

  4. 高效查看MySQL帮助文档的方法

    在mysql的使用过程中, 可能经常会遇到以下问题: 某个操作语法忘记了, 如何快速查找? 如何快速知道当前版本上某个字段类型的取值范围? 当前版本都支持哪些函数?希望有例子说明.. 当前版本是否支持 ...

  5. 3D拓扑自动布局之Web Workers篇

    2D拓扑的应用在电信网管和电力SCADA领域早已习以为常了,随着OpenGL特别是WebGL技术的普及,3D方式的数据可视化也慢慢从佛殿神堂步入了寻常百姓家,似乎和最近高档会所被整改为普通茶馆是一样的 ...

  6. QCustomplot使用分享(六) 坐标轴和网格线

    一.概述 前边已经写了5篇对QCustomPlot的讲解,看过上述的几篇文章后,基本就能做一些简单的使用了,但是如果想要做到高度的控制图表,那么坐标轴将是很重要的一部分,因为坐标轴就是图表的一个参考系 ...

  7. SQL Server 诊断查询-(4)

    Query #41 Memory Clerk Usage -- Memory Clerk Usage for instance -- Look for high value for CACHESTOR ...

  8. 给你的博客加上“Fork me on Github”彩带

    起 如今,随着Git的大热以及Github的优越性,许多知名开源项目都将源代码托管到Github上了.在Github上不仅可以托管自己的开源项目,还可以Fork人家的源代码,给自己感兴趣的项目评价(s ...

  9. 从零开始,CentOS6安装ghost博客

    买了个Bandwagon的VPS来科学上网的,寻思着空间还大顺便做个博客呗. 然后就安装了AMH面板,再搞了个wordpress博客玩玩. 接触到Ghost博客的时候,心血来潮想装一个. 然后就试着搞 ...

  10. 模拟浏览器搜索功能(Ctrl + F)

    写的匆忙,示意一下,有待完善.把以下代码复制到文本文件中,把文件扩展名改为.html就可以运行了. <html> <head> <style type="tex ...