How to animate layer shadowOpacity?
I have a view on which I've set the layerOpacity to 1.
theView.layer.shadowOpaci开发者_JS百科ty = 1.0;
This looks fine when the view is farther down the screen. When I move this view up to be flush with another view that has a shadow, they don't look good. Is there a way I can animate the shadowOpacity
on my layer to be 0? I tried using an animation block but it seems as if this property is not animatable.
EDIT: Request for code that doesn't work:
[UIView animateWithDuration:1.0 animations:^{
splitView2.layer.shadowOpacity = 0;}
completion:NULL];
This will work properly:
#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;
For 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
I've put above code in a little extension of 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
}
}
Usage like:
animateLayer(\.shadowOffset, to: CGSize(width: 3, height: 3), duration:1)
animateLayer(\.shadowOpacity, to: 0.4, duration: 1)
It's not thoroughly tested. but worked for me. (Also posted here)
The below code work for me
1)Add QuartzCore frame work 2)Import QuartzCore frame work
Add the following Code in the required place
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"];
It will works. Change the format of the code as per your requirement
Here's a material design like take on some of the above with animations It's also available here as framework through 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()
}
精彩评论