【问题标题】:Adding glow effect to UIButton - iOS为 UIButton 添加发光效果 - iOS
【发布时间】:2012-07-19 07:51:41
【问题描述】:

我有一个 UIButton,它是一个徽标。此徽标按钮将永远发光,但在触摸时会停止发光。它就像一个发光的动画。

有什么建议吗?

  Undefined symbols for architecture i386:
 "_OBJC_CLASS_$_CABasicAnimation", referenced from:
 objc-class-ref in UIView+Glow.o
 "_OBJC_CLASS_$_CAMediaTimingFunction", referenced from:
  objc-class-ref in UIView+Glow.o
  "_kCAMediaTimingFunctionEaseInEaseOut", referenced from:
  -[UIView(Glow) startGlowing] in UIView+Glow.o
   ld: symbol(s) not found for architecture i386
   clang: error: linker command failed with exit code 1 (use -v to see invocation)

【问题讨论】:

  • 您说的是带有标签(文本)的按钮还是自定义图形按钮?
  • 哎呀,我在下面为带有标签的按钮写了答案。您可以尝试类似的方法(使用 button.imageView.layer) - 您必须稍微调整阴影颜色。或者简单地使用两张图片(一张有发光,一张没有)以获得更多自定义效果。

标签: ios xcode quartz-graphics


【解决方案1】:

我喜欢我的“额外特殊”按钮的这种发光 + 增长/收缩动画:

-(void)makeViewShine:(UIView*) view
{
view.layer.shadowColor = [UIColor yellowColor].CGColor;
view.layer.shadowRadius = 10.0f;
view.layer.shadowOpacity = 1.0f;
view.layer.shadowOffset = CGSizeZero;


[UIView animateWithDuration:0.7f delay:0 options:UIViewAnimationOptionAutoreverse | UIViewAnimationCurveEaseInOut | UIViewAnimationOptionRepeat | UIViewAnimationOptionAllowUserInteraction  animations:^{

    [UIView setAnimationRepeatCount:15];

    view.transform = CGAffineTransformMakeScale(1.2f, 1.2f);


} completion:^(BOOL finished) {

    view.layer.shadowRadius = 0.0f;
    view.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
}];

}

【讨论】:

    【解决方案2】:

    我建议你使用Glow Category of UIView made by secret lab

    示例可用here

    【讨论】:

    • 嘿,我想用这个但我不能。您能否提供一些有关如何使用它的示例。提前致谢
    • 太棒了!谢谢你,我喜欢它。
    • 我之前在一个项目中使用过Glow类,效果很好。如果您想让它更精细,也可以根据您的需要轻松定制。
    • 在哪里可以找到使用它的示例?
    【解决方案3】:

    斯威夫特 5

    1. 使用动画创建 UIView 扩展

    2. 在文本字段、按钮、视图(UIView 的任何子类)上使用它

    注意:您可以更改值并尝试获得所需的效果。

    UIView 扩展

    import UIKit
    
    extension UIView {
        enum GlowEffect: Float {
            case small = 0.4, normal = 2, big = 15
        }
    
        func doGlowAnimation(withColor color: UIColor, withEffect effect: GlowEffect = .normal) {
            layer.masksToBounds = false
            layer.shadowColor = color.cgColor
            layer.shadowRadius = 0
            layer.shadowOpacity = 1
            layer.shadowOffset = .zero
    
            let glowAnimation = CABasicAnimation(keyPath: "shadowRadius")
            glowAnimation.fromValue = 0
            glowAnimation.toValue = effect.rawValue
            glowAnimation.beginTime = CACurrentMediaTime()+0.3
            glowAnimation.duration = CFTimeInterval(0.3)
            glowAnimation.fillMode = .removed
            glowAnimation.autoreverses = true
            glowAnimation.isRemovedOnCompletion = true
            layer.add(glowAnimation, forKey: "shadowGlowingAnimation")
        }
    }
    

    使用方法:

    //TextField with border
    textField.doGlowAnimation(withColor: UIColor.red, withEffect: .big)
    
    //Label
    label.doGlowAnimation(withColor: label.textColor, withEffect: .small)
    
    //Button
    button.doGlowAnimation(withColor: UIColor.red, withEffect: .big)
    

    【讨论】:

    • 如何永久添加发光效果?
    • 添加属性glowAnimation.repeatCount = .infinity 移除glowAnimation.isRemovedOnCompletion = true 你可以使用属性来获得你想要的结果。
    • 我会在 func doGlowAnimation(... forever: Bool = false) 上添加一个参数,然后执行里面的逻辑。
    【解决方案4】:

    发光代码取自:Creating a Glow Effect for UILabel and UIButton

    首先,您需要导入 QuartzCore 框架:

    #import <QuartzCore/QuartzCore.h>
    

    当您创建按钮时(或在viewDidLoad,取决于您的代码结构)添加 这段代码:

    UIColor *color = button.currentTitleColor;
    button.titleLabel.layer.shadowColor = [color CGColor];
    button.titleLabel.layer.shadowRadius = 4.0f;
    button.titleLabel.layer.shadowOpacity = .9;
    button.titleLabel.layer.shadowOffset = CGSizeZero;
    button.titleLabel.layer.masksToBounds = NO;
    

    您需要注意两个事件:UIControlEventTouchDownUIControlEventTouchUpInside

    UIControlEventTouchDown 处理程序中,您将添加代码:

    UIColor *color = [UIColor clearColor];
    button.titleLabel.layer.shadowColor = [color CGColor];
    

    UIControlEventUpInside 处理程序中,您将添加代码:

    UIColor *color = button.currentTitleColor;
    button.titleLabel.layer.shadowColor = [color CGColor];
    

    同样,实现细节取决于您是通过编程方式还是通过 Interface Builder 创建按钮,但我相信您从这里开始就可以解决这个问题。

    编辑:对于自定义按钮,只需添加以下代码即可:

    [button setImage:[UIImage imageNamed:@"buttonWithGlow.png"]
            forState:UIControlStateNormal];
    [button setImage:[UIImage imageNamed:@"buttonWithNoGlow.png"] 
            forState:UIControlStateHighlighted];
    

    【讨论】:

    • 我猜这适用于普通按钮。对带有图像的自定义按钮有什么建议吗?
    • 有两种方法(在你的问题下面的推荐中描述)。在每种情况下,您都必须监视 UIControlEventDownInsideUIControlEventTouchUpInside 事件。
    • 它不会在触摸时发光,但不会停止。这就是问题
    • 如果我理解正确,您想在创建时添加发光,按下按钮时将其移除 (UIControlEventTouchDownInside) 并在释放时再次添加 (UIControlEventTouchUpInside)?
    • 不。它就像一个按钮,无论你是否按下它都会亮起和熄灭。
    【解决方案5】:

    这是我的答案....

    使用类别

    /* ****FAQ?
    
     1.how to add glow effect on uibutton?
     [UIButton glowUIButton:playButton];
    
     2.how to remove effect on uibutton?
     [UIButton removeGlowUIButton:playButton];
    
     Ends*** */
    
    #import <UIKit/UIKit.h>
    @interface UIButton (BlinkEffect)
    //blink effect category
    +( void) glowUIButton:(UIButton *)inputButton;
    //remove blink effect
    +(void) removeGlowUIButton:(UIButton *)inputButton;
    @end
    
    #import "UIButton+BlinkEffect.h"
    
    @implementation UIButton (BlinkEffect)
    
    +(void) glowUIButton:(UIButton *)inputButton
    {
        //add blink effect
        CALayer *viewLayer = inputButton.layer;
        viewLayer.shadowOffset = CGSizeMake(0,0);
        CGFloat radius = CGRectGetWidth(inputButton.bounds)/2.0;
        viewLayer.shadowColor = [[UIColor whiteColor] CGColor];
        viewLayer.shadowPath = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(-7,-5.5, 2.5 * (radius), 2.5 * radius) cornerRadius:radius].CGPath;
        viewLayer.shadowRadius = 5.0f;
        viewLayer.shadowOpacity = 1.0f;
    
        //Let's animate it while we're at it.
        CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"shadowOpacity"];
        animation.duration =0.7;
        animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
        animation.fromValue = [NSNumber numberWithFloat:1.0];
        animation.toValue = [NSNumber numberWithFloat:0.0];
        animation.autoreverses = YES;
        animation.repeatCount = 1.0 / 0.0;
        [viewLayer addAnimation:animation forKey:@"shadowOpacity"];
    
    }
    
    +(void)removeGlowUIButton:(UIButton *)inputButton
    {
        CALayer *viewLayer = inputButton.layer;
        viewLayer.shadowColor = [[UIColor clearColor] CGColor];
        [viewLayer removeAnimationForKey:@"shadowOpacity"];
    }
    @end
    

    【讨论】:

      【解决方案6】:

      斯威夫特 5

      alegelos 用 shadowOpacity、autorepeat 和 shadowOffset 回答:

      extension UIView {
      
        enum GlowEffect: Float {
          case small = 0.4, normal = 5, big = 15
        }
        
        func doGlowAnimation(withColor color: UIColor, withEffect effect: GlowEffect = .normal) {
          layer.masksToBounds = false
          layer.shadowColor = color.cgColor
          layer.shadowRadius = 0
          layer.shadowOpacity = 1
          layer.shadowOffset = CGSize(width: 0, height: 3)
          
          let glowAnimationRadius = CABasicAnimation(keyPath: "shadowRadius")
          glowAnimationRadius.fromValue = 0
          glowAnimationRadius.toValue = effect.rawValue
          glowAnimationRadius.beginTime = CACurrentMediaTime()+0.3
          glowAnimationRadius.duration = CFTimeInterval(1.3)
          glowAnimationRadius.fillMode = .removed
          glowAnimationRadius.autoreverses = true
          glowAnimationRadius.repeatCount = .infinity
          layer.add(glowAnimationRadius, forKey: "shadowGlowingAnimationRadius")
          
          let glowAnimationOpacity = CABasicAnimation(keyPath: "shadowOpacity")
          glowAnimationOpacity.fromValue = 0
          glowAnimationOpacity.toValue = 1
          glowAnimationOpacity.beginTime = CACurrentMediaTime()+0.3
          glowAnimationOpacity.duration = CFTimeInterval(1.3)
          glowAnimationOpacity.fillMode = .removed
          glowAnimationOpacity.autoreverses = true
          glowAnimationOpacity.repeatCount = .infinity
          layer.add(glowAnimationOpacity, forKey: "shadowGlowingAnimationOpacity")
        }
      }
      

      【讨论】:

        最近更新 更多