【问题标题】:How to animate layer shadowOpacity?如何为图层 shadowOpacity 设置动画?
【发布时间】:2011-05-29 00:05:10
【问题描述】:

我有一个视图,我已将 layerOpacity 设置为 1。

    theView.layer.shadowOpacity = 1.0;

当视图位于屏幕下方时,这看起来不错。当我将此视图向上移动以与另一个有阴影的视图齐平时,它们看起来不太好。有没有办法可以将我图层上的shadowOpacity 设置为 0?我尝试使用动画块,但似乎这个属性是不可动画的。

编辑:请求无效的代码:

[UIView animateWithDuration:1.0 animations:^{
    splitView2.layer.shadowOpacity = 0;}
                 completion:NULL];

【问题讨论】:

  • 来自 Apple 的文档:“@property float shadowOpacity 指定接收者阴影的不透明度。Animatable。”你能发布一些不起作用的代码吗?
  • 在 UIView animateWithDuration 中不起作用
  • @JoeBlow:正确,这就是我写我发布的代码不起作用的原因。您必须直接使用 Core Animation,因为 UIView 没有为它提供隐式动画。
  • 嗨,须藤!为了清楚起见,请注意@Costique 的评论:我正在回复该评论。干杯!感谢您提出这个方便的问题,它在下面得到了很好的答案。

标签: iphone objective-c cocoa-touch uiview quartz-graphics


【解决方案1】:

这将正常工作:

#import <QuartzCore/CAAnimation.h>

CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"shadowOpacity"];
anim.fromValue = [NSNumber numberWithFloat:1.0];
anim.toValue = [NSNumber numberWithFloat:0.0];
anim.duration = 1.0;
[vv.layer addAnimation:anim forKey:@"shadowOpacity"];
vv.layer.shadowOpacity = 0.0;

对于 Swift 3.0:

 let animation = CABasicAnimation(keyPath: "shadowOpacity")
 animation.fromValue = layer.shadowOpacity
 animation.toValue = 0.0
 animation.duration = 1.0
 view.layer.add(animation, forKey: animation.keyPath)
 view.layer.shadowOpacity = 0.0

【讨论】:

  • 如果没有设置 vv.layer.shadowOpacity = 0.0;在最后一行,动画将完成,但之后它会跳回旧层
  • 如果你想打开而不是关闭阴影,这两部分很重要:anim.removedOnCompletion = NO; anim.fillMode = kCAFillModeForwards;
  • @moby 感谢您的评论。这是让这个答案发挥作用的关键。
  • 可以用anim.removeOnCompletion应该去哪里更新代码sn-p吗?
  • 重要提示:在 iOS 模拟器中启用“调试 > 慢动画”时,通过此方法实现的动画可能不会以降低的速度运行。这个让我在杂草丛生了很长一段时间。具体来说,我认为我的动画设置不正确,因为我的自定义视图转换运行速度降低,但我的 CABasic 动画全速运行。
【解决方案2】:

我把上面的代码放在了 UIView 的一个小扩展中:

extension UIView {

func animateLayer<Value>(_ keyPath: WritableKeyPath<CALayer, Value>, to value:Value, duration: CFTimeInterval) {

    let keyString = NSExpression(forKeyPath: keyPath).keyPath
    let animation = CABasicAnimation(keyPath: keyString)
    animation.fromValue = self.layer[keyPath: keyPath]
    animation.toValue = value
    animation.duration = duration
    self.layer.add(animation, forKey: animation.keyPath)
    var thelayer = layer
    thelayer[keyPath: keyPath] = value
}
}

用法如下:

animateLayer(\.shadowOffset, to: CGSize(width: 3, height: 3), duration:1)
animateLayer(\.shadowOpacity, to: 0.4, duration: 1)

它没有经过彻底的测试。但为我工作。 (也发帖here

【讨论】:

    【解决方案3】:

    下面的代码对我有用

    1)添加QuartzCore框架 2)导入QuartzCore框架

    在需要的地方添加如下代码

    UIImageView * glowimageview = [[[UIImageView alloc]init]autorelease];
        [glowimageview setFrame:CGRectMake(500,400,200,200)];
        [glowimageview setImage:[UIImage imageNamed:@"144.png"]];
        [sender addSubview:glowimageview];
    
        glowimageview.layer.shadowColor = [UIColor redColor].CGColor;
        glowimageview.layer.shadowRadius = 10.0f;
        glowimageview.layer.shadowOpacity = 1.0f;
        glowimageview.layer.shadowOffset = CGSizeZero;
    
        CABasicAnimation *shadowAnimation = [CABasicAnimation animationWithKeyPath:@"shadowOpacity"];
        shadowAnimation.duration=1.0;
        shadowAnimation.repeatCount=HUGE_VALF;
        shadowAnimation.autoreverses=YES;
        shadowAnimation.fromValue = [NSNumber numberWithFloat:1.0];
        shadowAnimation.toValue = [NSNumber numberWithFloat:0.0];
        [glowimageview.layer addAnimation:shadowAnimation forKey:@"shadowOpacity"];
    

    它会起作用的。根据您的要求更改代码的格式

    【讨论】:

      【解决方案4】:

      这是一个材料设计,类似于上面的一些动画 它也可以通过 Carthage https://github.com/sevenapps/SVNMaterialButton 以框架形式在此处使用

      public init(frame: CGRect, color: UIColor) {
          super.init(frame: frame)
          self.backgroundColor = color
          self.layer.masksToBounds = false
          self.layer.borderWidth = 1.0
          self.layer.shadowColor = UIColor.black.cgColor
          self.layer.shadowOpacity = 0.8
          self.layer.shadowRadius = 8
          self.layer.shadowOffset = CGSize(width: 8.0, height: 8.0)
      }
      
      required public init?(coder aDecoder: NSCoder) {
          fatalError("This class is not set up to be instaciated with coder use init(frame) instead")
      }
      
      public override func layoutSubviews() {
          super.layoutSubviews()
          self.layer.cornerRadius = self.frame.height / 4
      }
      
      public override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
          self.animate(to: 0.5, and: CGSize(width: 5.0, height: 5.0), with: 0.5)
          super.touchesBegan(touches, with: event)
      }
      
      public override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
          self.animate(to: 0.8, and: CGSize(width: 8.0, height: 8.0), with: 0.5)
          super.touchesBegan(touches, with: event)
      }
      
      private func animate(to opacity: Double, and offset: CGSize, with duration: Double){
          CATransaction.begin()
          let opacityAnimation = CABasicAnimation(keyPath: "shadowOpacity")
          opacityAnimation.toValue = opacity
          opacityAnimation.duration = duration
          opacityAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
          opacityAnimation.fillMode = kCAFillModeBoth
          opacityAnimation.isRemovedOnCompletion = false
      
          let offsetAnimation = CABasicAnimation(keyPath: "shadowOffset")
          offsetAnimation.toValue = offset
          offsetAnimation.duration = duration
          offsetAnimation.timingFunction = opacityAnimation.timingFunction
          offsetAnimation.fillMode = opacityAnimation.fillMode
          offsetAnimation.isRemovedOnCompletion = false
      
          self.layer.add(offsetAnimation, forKey: offsetAnimation.keyPath!)
          self.layer.add(opacityAnimation, forKey: opacityAnimation.keyPath!)
          CATransaction.commit()
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-08-31
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多