I am trying to animate the mask layer on a UIView.
Basically this code displays the image below:
let bounds: CGRect = self.manualWBMaskView!.bounds
let maskLayer: CAShapeLayer = CAShapeLayer()
maskLayer.frame = bounds
maskLayer.fillColor = UIColor.blackColor().CGColor
let screenWith : CGFloat = UIScreen.mainScreen().bounds.width
let roundedRectFrame : CGRect = CGRectMake(self.manualWBMaskView!.bounds.midX - (screenWith/4), self.manualWBMaskView!.bounds.midY - (screenWith/4), screenWith/2, screenWith/2)
let path: UIBezierPath = UIBezierPath(roundedRect:roundedRectFrame, cornerRadius:10 )
path.appendPath(UIBezierPath(rect: bounds))
maskLayer.path = path.CGPath
maskLayer.fillRule = kCAFillRuleEvenOdd
self.manualWBMaskView!.layer.mask = maskLayer
I want it to animate to that position of the cutout from being full screen to above position:
I tried UIView animation, and no luck. Since I already have a CAShapeLayer, I should be able to animate that?
EDIT**
Here's the animation code I tried, which didn't work:
//Before Animation Make the Mask fill the whole view:
self.manualWBMaskView!.layer.mask = self.manualWBMaskView!.bounds
var duration: NSTimeInterval = 0.8
CATransaction.begin()
CATransaction[kCATransactionAnimationDuration] = Int(duration)
self.manualWBMaskView!.layer.mask = CGRectMake(self.manualWBMaskView!.bounds.midX - (screenWith/4), self.manualWBMaskView!.bounds.midY - (screenWith/4), screenWith/2, screenWith/2)
CATransaction.commit()
As per 'originaluser2's reply below, I have this:
func presentMaskScreenWithAnimation () {
let bounds: CGRect = self.manualWBMaskView!.bounds
let maskLayer: CAShapeLayer = CAShapeLayer()
maskLayer.frame = bounds
maskLayer.fillColor = UIColor.blackColor().CGColor
let screenWith : CGFloat = UIScreen.mainScreen().bounds.width
let roundedRectFrame : CGRect = self.manualWBMaskView.bounds
let path: UIBezierPath = UIBezierPath(roundedRect:roundedRectFrame, cornerRadius:0 )
path.appendPath(UIBezierPath(rect: bounds))
maskLayer.path = path.CGPath
maskLayer.fillRule = kCAFillRuleEvenOdd
self.manualWBMaskView!.layer.mask = maskLayer
// define your new path to animate the mask layer to
let screenWith2 : CGFloat = UIScreen.mainScreen().bounds.width
let roundedRectFrame2 : CGRect = CGRectMake(self.manualWBMaskView!.bounds.midX - (screenWith2/4), self.manualWBMaskView!.bounds.midY - (screenWith2/4), screenWith2/2, screenWith2/2)
let path2 = UIBezierPath(roundedRect:roundedRectFrame2, cornerRadius:10 )
// create new animation
let anim = CABasicAnimation(keyPath: "path")
// from value is the current mask path
anim.fromValue = maskLayer.path
// to value is the new path
anim.toValue = path2.CGPath
// duration of your animation
anim.duration = 5.0
// custom timing function to make it look smooth
anim.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
// add animation
maskLayer.addAnimation(anim, forKey: nil)
// update the path property on the mask layer, using a CATransaction to prevent an implicit animation
CATransaction.begin()
CATransaction.setDisableActions(true)
maskLayer.path = path2.CGPath
maskLayer.fillRule = kCAFillRuleEvenOdd
CATransaction.commit()
}
It does the animation; However, I got two issues now: 1. Shape is all off during the animation, yet if come together at the end of the animation. (Screenshot below)
- Mask is inverted. It 's visible inside the shape, but transparent around it. I need the opposite. Inside the shape being transparent.
manualWBMaskView
? You're just asking for a crash. Please learn how to properly deal with optionals. – Mimicry