Skip to content

Instantly share code, notes, and snippets.

@thecodewarrior
Created February 11, 2018 23:10
Show Gist options
  • Save thecodewarrior/e317eb20c0f6a58ee69f9a668f65f3a5 to your computer and use it in GitHub Desktop.
Save thecodewarrior/e317eb20c0f6a58ee69f9a668f65f3a5 to your computer and use it in GitHub Desktop.
An extension that allows you to freely adjust the amount of blur on a UIVisualEffectView. Tested on iOS 11.2 with Swift 4
extension UIVisualEffectView {
public var adjuster: UIVisualEffectViewAdjuster {
get {
if let adjuster = objc_getAssociatedObject( self, &UIVisualEffectViewAdjuster.key) as? UIVisualEffectViewAdjuster {
return adjuster
} else {
let adjuster = UIVisualEffectViewAdjuster(effectView: self)
objc_setAssociatedObject( self, &UIVisualEffectViewAdjuster.key, adjuster, .OBJC_ASSOCIATION_RETAIN)
return adjuster
}
}
}
}
public class UIVisualEffectViewAdjuster {
static var key = "visualEffectViewAdjuster"
private weak var effectView: UIVisualEffectView!
fileprivate init(effectView: UIVisualEffectView) {
self.effectView = effectView
self.effect = effectView.effect
}
public var contentView: UIView { get { return effectView.contentView } }
public var effectAmount: Float = 1 {
didSet {
updateAmount()
}
}
private var animator: UIViewPropertyAnimator? = nil
public var effect: UIVisualEffect? {
didSet {
animator = resetAnimation()
}
}
private func resetAnimation() -> UIViewPropertyAnimator {
if let animator = animator {
animator.stopAnimation(true)
self.animator = nil
}
effectView.effect = effect
effectView.contentView.subviews.forEach { $0.alpha = 1.0 }
let animator_ = UIViewPropertyAnimator(duration: 20, curve: .linear) {
self.effectView.effect = nil
self.effectView.contentView.subviews.forEach { $0.alpha = 0.0 }
}
return animator_
}
private func updateAmount() {
if(effectAmount == 0) {
if(animator?.state != .stopped) {
animator?.stopAnimation(true)
animator = nil
}
effectView.effect = nil
} else if(effectAmount == 1) {
if(animator?.state != .stopped) {
animator?.stopAnimation(true)
animator = nil
}
effectView.effect = effect
} else if(effect != nil) {
animator = animator ?? resetAnimation()
animator!.fractionComplete = CGFloat(min(max(1-effectAmount, 10e-8), 1-10e-8))
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment