2

I have been exploring this questions through playgrounds for days now without finding any solution.

I am been managing to create a hole in a blurred UIView. Now I am wondering how to animate the radius of this circle, ergo animating the blurred view's mask's path.

Here is my code so far:

import Foundation
import UIKit
import PlaygroundSupport

let contentRect = CGRect(x: 0, y: 0, width: 400, height: 400)
let contentView = UIView(frame: contentRect)
contentView.backgroundColor = .white

PlaygroundPage.current.liveView = contentView

let image = UIImage(named: "landscape.jpg")
let imageView = UIImageView(frame: contentRect, image: image)
imageView.contentMode = .scaleAspectFill

let blur = UIBlurEffect(style: .light)
let blurView = UIVisualEffectView(effect: blur)
blurView.frame = contentRect

let path = UIBezierPath(rect: contentRect)
let circle = UIBezierPath(ovalIn: CGRect(x: 50, y: 50, width: 300, height: 300))
path.append(circle)
path.usesEvenOddFillRule = true

let toPath = UIBezierPath(rect: contentRect)
let toCircle = UIBezierPath(ovalIn: CGRect(x: 150, y: 150, width: 100, height: 100))
toPath.append(toCircle)
toPath.usesEvenOddFillRule = true

let hole = CAShapeLayer()
hole.path = path.cgPath
hole.fillColor = UIColor.green.cgColor
hole.fillRule = kCAFillRuleEvenOdd

let mask = UIView(frame: contentRect)

contentView.addSubview(imageView)

contentView.addSubview(blurView)

mask.layer.addSublayer(hole)

blurView.mask = mask

I have been trying this, without success:

let animation = CABasicAnimation(keyPath: "path")
animation.fromValue = hole.path
animation.toValue = toPath.cgPath
animation.duration = 2
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn)
hole.add(animation, forKey: nil)

CATransaction.begin()
CATransaction.disableActions()
hole.path = toPath.cgPath
CATransaction.commit()

Also tried UIView.animate(... or extracting blurView.layer.sublayers to add them to my contentView, but it just gets messy.

Another approach would be to use a CGAffineTransform, which I tried, but the blur gets disrupted. Plus I have trouble to use a workaround when I feel so close to a solution.

Any help would be greatly appreciated! Thanks!

adauguet
  • 988
  • 8
  • 18
  • Did you try it on a real device as well? I have also experienced animations that did not work in the Playground but worked fine on a device... – Alladinian Mar 13 '17 at 16:05
  • I suddenly feel stupid. Wait. – adauguet Mar 13 '17 at 16:12
  • Okay I just checked and I have the same problem on an app, simulator or device. Thanks for the advice though. – adauguet Mar 13 '17 at 16:21
  • Sure... challenge accepted :P – Alladinian Mar 13 '17 at 16:22
  • 1
    OK here are some findings... The good news is that a general solution is possible by animating `layer.mask` instead of (`UIView's`) `mask`. The bad news is that this is not working with a `UIVisualEffectView` (as reported on other questions like [this one](http://stackoverflow.com/questions/39595047/uivisualeffectview-with-mask-layer)) :/ – Alladinian Mar 14 '17 at 16:38

0 Answers0