GlowView

简介:

GlowView

 

效果

 

说明

这是本人第二次写辉光view了,这是改进版本

 

源码

https://github.com/YouXianMing/UI-Component-Collection



//
//  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   animationDuration              glowDuration              animationDuration
//

#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.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


目录
相关文章
|
7月前
|
存储 安全 测试技术
《手把手教你》系列技巧篇(六十三)-java+ selenium自动化测试 - cookie -上篇(详细教程)
【6月更文挑战第4天】本文介绍了Cookie和Session的概念及其用途。Cookie是服务器发送到浏览器并存储在本地的小型文本文件,用于记录用户信息,如登录状态。它分为会话Cookie(关闭浏览器即消失)和永久Cookie(设置过期时间)。Session则是在服务器端保存用户状态的一种方式,比Cookie更安全,但会占用服务器资源。Selenium提供了操作Cookie的API,包括添加、删除和获取Cookie。文章还提到了Cookie的优缺点,如大小限制和潜在的安全风险。
150 1
《手把手教你》系列技巧篇(六十三)-java+ selenium自动化测试 - cookie -上篇(详细教程)
|
7月前
|
Java 计算机视觉
图像处理之边缘褪化效果
图像处理之边缘褪化效果
35 0
x86_64-linux-gnu/libgdk-x11-2.0.so: error adding symbols: DSO missing from command line
x86_64-linux-gnu/libgdk-x11-2.0.so: error adding symbols: DSO missing from command line
254 0
|
JavaScript 前端开发
Vue简单语法
Vue简单语法
108 0
|
前端开发 数据安全/隐私保护
HTML登录页面
本文用最通俗的语言,一步步教会大家CSS构建登录页面。首先构建。
128 0
HTML登录页面
Java 如何优雅的在循环中删除元素
Java 如何优雅的在循环中删除元素
|
存储 算法 JavaScript
JS数据结构与算法-二叉树和二叉查找树
树是一种非线性的数据结构,以分层的方式存储数据。树被用来存储具有层级关系的结构,比如文件系统中的文件;树还被用来存储有序列表。 二叉树与二叉查找树二叉树是一种特殊的树,它的子节点个数不超过两个;一个父节点的两个子节点分别称为左节点和右节点。
1083 0
|
12天前
|
弹性计算 人工智能 安全
对话 | ECS如何构筑企业上云的第一道安全防线
随着中小企业加速上云,数据泄露、网络攻击等安全威胁日益严重。阿里云推出深度访谈栏目,汇聚产品技术专家,探讨云上安全问题及应对策略。首期节目聚焦ECS安全性,提出三道防线:数据安全、网络安全和身份认证与权限管理,确保用户在云端的数据主权和业务稳定。此外,阿里云还推出了“ECS 99套餐”,以高性价比提供全面的安全保障,帮助中小企业安全上云。
201895 14
对话 | ECS如何构筑企业上云的第一道安全防线
|
4天前
|
供应链 监控 安全
对话|企业如何构建更完善的容器供应链安全防护体系
随着云计算和DevOps的兴起,容器技术和自动化在软件开发中扮演着愈发重要的角色,但也带来了新的安全挑战。阿里云针对这些挑战,组织了一场关于云上安全的深度访谈,邀请了内部专家穆寰、匡大虎和黄竹刚,深入探讨了容器安全与软件供应链安全的关系,分析了当前的安全隐患及应对策略,并介绍了阿里云提供的安全解决方案,包括容器镜像服务ACR、容器服务ACK、网格服务ASM等,旨在帮助企业构建涵盖整个软件开发生命周期的安全防护体系。通过加强基础设施安全性、技术创新以及倡导协同安全理念,阿里云致力于与客户共同建设更加安全可靠的软件供应链环境。