效果如下:
本人已经将实现封装到一个分类里面,可以直接调用:
// label UILabel *glowLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.width, 40)]; glowLabel.center = self.view.center; glowLabel.text = @"LeiLuRong..."; glowLabel.textAlignment = NSTextAlignmentCenter; glowLabel.textColor = [UIColor whiteColor]; glowLabel.font = [UIFont systemFontOfSize:28]; [self.view addSubview:glowLabel]; glowLabel.glowRadius = @(2.f); glowLabel.glowOpacity = @(1.f); glowLabel.glowColor = [UIColor cyanColor]; glowLabel.glowDuration = @(1.f); glowLabel.hideDuration = @(0.3); glowLabel.glowAnimationDuration = @(1.5f); [glowLabel createGlowLayer]; [glowLabel insertGlowLayer]; [glowLabel startGlowLoop]; // imageView UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 40, 40)]; imageView.center = CGPointMake(self.view.center.x, 400); imageView.image = [UIImage imageNamed:@"collection_new"]; [self.view addSubview:imageView]; imageView.glowRadius = @(2.f); imageView.glowOpacity = @(0.5f); imageView.glowColor = [UIColor whiteColor]; imageView.glowDuration = @1.5; imageView.hideDuration = @0.5; imageView.glowAnimationDuration = @1.5; [imageView createGlowLayer]; [imageView insertGlowLayer]; [imageView startGlowLoop]; 分类: UIView+GlowView.h /** * 辉光的颜色 */ @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)glowToshowAnimated:(BOOL)animated; /** * 隐藏辉光 */ - (void)glowToHideAnimated:(BOOL)animated; /** * 开始循环辉光 */ - (void)startGlowLoop; UIView+GlowView.m #import "UIView+GlowView.h" #import @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)glowToshowAnimated:(BOOL)animated { self.glowLayer.shadowColor = [self accessGlowColor].CGColor; self.glowLayer.shadowRadius = [self accessGlowRadius].floatValue; if (animated) { 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:@"glowLayerOpacity"]; } else { [self.glowLayer removeAnimationForKey:@"glowLayerOpacity"]; self.glowLayer.opacity = [self accessGlowOpacity].floatValue; } } - (void)glowToHideAnimated:(BOOL)animated { self.glowLayer.shadowColor = [self accessGlowColor].CGColor; self.glowLayer.shadowRadius = [self accessGlowRadius].floatValue; if (animated) { 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:@"glowLayerOpacity"]; } else { [self.glowLayer removeAnimationForKey:@"glowLayerOpacity"]; self.glowLayer.opacity = 0.f; } } - (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()); __weak UIView *weakSelf = self; dispatch_source_set_timer(self.dispatchSource, dispatch_time(DISPATCH_TIME_NOW, 0), NSEC_PER_SEC * seconds, 0); dispatch_source_set_event_handler(self.dispatchSource, ^{ [weakSelf glowToshowAnimated:YES]; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * delaySeconds), dispatch_get_main_queue(), ^{ [weakSelf glowToHideAnimated:YES]; }); }); dispatch_resume(self.dispatchSource); } } #pragma mark - 处理数据越界问题 - (NSNumber *)accessGlowOpacity { if (self.glowOpacity) { if (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属性 - (void)setDispatchSource:(dispatch_source_t)dispatchSource { objc_setAssociatedObject(self, @selector(dispatchSource), dispatchSource, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (dispatch_source_t)dispatchSource { return objc_getAssociatedObject(self, _cmd); } - (void)setGlowColor:(UIColor *)glowColor { objc_setAssociatedObject(self, @selector(glowColor), glowColor, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (UIColor *)glowColor { return objc_getAssociatedObject(self, _cmd); } - (void)setGlowOpacity:(NSNumber *)glowOpacity { objc_setAssociatedObject(self, @selector(glowOpacity), glowOpacity, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (NSNumber *)glowOpacity { return objc_getAssociatedObject(self, _cmd); } - (void)setGlowRadius:(NSNumber *)glowRadius { objc_setAssociatedObject(self, @selector(glowRadius), glowRadius, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (NSNumber *)glowRadius { return objc_getAssociatedObject(self, _cmd); } - (void)setGlowAnimationDuration:(NSNumber *)glowAnimationDuration { objc_setAssociatedObject(self, @selector(glowAnimationDuration), glowAnimationDuration, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (NSNumber *)glowAnimationDuration { return objc_getAssociatedObject(self, _cmd); } - (void)setGlowDuration:(NSNumber *)glowDuration { objc_setAssociatedObject(self, @selector(glowDuration), glowDuration, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (NSNumber *)glowDuration { return objc_getAssociatedObject(self, _cmd); } - (void)setHideDuration:(NSNumber *)hideDuration { objc_setAssociatedObject(self, @selector(hideDuration), hideDuration, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (NSNumber *)hideDuration { return objc_getAssociatedObject(self, _cmd); } NSString * const _recognizerGlowLayer = @"_recognizerGlowLayer"; - (void)setGlowLayer:(CALayer *)glowLayer { objc_setAssociatedObject(self, @selector(glowLayer), glowLayer, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (CALayer *)glowLayer { return objc_getAssociatedObject(self, _cmd); } @end
源码已经放在GitHub:https://github.com/Fendouzhe/LRAnimations,有兴趣的欢迎下载查看,有帮助可以star,谢谢!