Skip to content

Instantly share code, notes, and snippets.

@iamtchelo
Forked from oboje/UIVisualEffect.swift
Created August 6, 2017 22:14
Show Gist options
  • Select an option

  • Save iamtchelo/9a4581802daf61d9bf5a96017f5af4fe to your computer and use it in GitHub Desktop.

Select an option

Save iamtchelo/9a4581802daf61d9bf5a96017f5af4fe to your computer and use it in GitHub Desktop.

Revisions

  1. @ilyapuchka ilyapuchka revised this gist Jan 21, 2017. 1 changed file with 3 additions and 3 deletions.
    6 changes: 3 additions & 3 deletions UIVisualEffect.swift
    Original file line number Diff line number Diff line change
    @@ -1,16 +1,16 @@
    extension UIVisualEffectView {

    fileprivate var filterLayer: CALayer? {
    private var filterLayer: CALayer? {
    return layer.sublayers?.first
    }

    fileprivate var blurFilter: NSObject? {
    private var blurFilter: NSObject? {
    return filterLayer?
    .filters?.flatMap({ $0 as? NSObject })
    .first(where: { $0.value(forKey: "name") as? String == "gaussianBlur" })
    }

    fileprivate var saturationFilter: NSObject? {
    private var saturationFilter: NSObject? {
    return filterLayer?
    .filters?.flatMap({ $0 as? NSObject })
    .first(where: { $0.value(forKey: "name") as? String == "colorSaturate" })
  2. @ilyapuchka ilyapuchka revised this gist Jan 21, 2017. No changes.
  3. @ilyapuchka ilyapuchka revised this gist Jan 20, 2017. 1 changed file with 14 additions and 111 deletions.
    125 changes: 14 additions & 111 deletions UIVisualEffect.swift
    Original file line number Diff line number Diff line change
    @@ -1,22 +1,3 @@
    //: Playground - noun: a place where people can play

    import UIKit
    import PlaygroundSupport
    import ObjectiveC

    let image = UIImage(named: "berlinerdom.jpg")!
    let imageView = UIImageView(image: image)
    imageView.frame.size.width = 540
    imageView.frame.size.height = 363
    let effectView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
    effectView.frame.size.width = 540//360
    effectView.frame.size.height = 363//242
    effectView.center = imageView.center
    imageView.addSubview(effectView)

    PlaygroundPage.current.liveView = imageView
    PlaygroundPage.current.needsIndefiniteExecution = true

    extension UIVisualEffectView {

    fileprivate var filterLayer: CALayer? {
    @@ -35,119 +16,41 @@ extension UIVisualEffectView {
    .first(where: { $0.value(forKey: "name") as? String == "colorSaturate" })
    }

    var blurRadius: CGFloat? {
    var blurRadius: CGFloat {
    get {
    return blurFilter?.value(forKey: kCIInputRadiusKey) as? CGFloat
    return blurFilter?.value(forKey: "inputRadius") as? CGFloat ?? 0
    }
    set {
    blurFilter?.setValue(newValue, forKey: kCIInputRadiusKey)
    blurFilter?.setValue(newValue, forKey: "inputRadius")
    if newValue == 0 { scale = 1 }
    }
    }

    var enableBlur: Bool {
    var saturationAmount: CGFloat {
    get {
    let dimLayer = layer.sublayers?.last?.opacity != 0
    return blurRadius != 0 && dimLayer
    return saturationFilter?.value(forKey: "inputAmount") as? CGFloat ?? 1
    }
    set {
    blurRadius = 0
    layer.sublayers?.last?.opacity = newValue ? 1 : 0
    saturationFilter?.setValue(newValue, forKey: "inputAmount")
    }
    }

    /// the same as saturation amount 1
    var enableSaturation: Bool {
    var scale: CGFloat? {
    get {
    return saturationFilter?.value(forKey: "enabled") as? Bool ?? false
    return filterLayer?.value(forKey: "scale") as? CGFloat
    }
    set {
    saturationFilter?.setValue(newValue, forKey: "enabled")
    filterLayer?.setValue(newValue, forKey: "scale")
    }
    }

    var saturationAmount: CGFloat? {
    var opacity: Float? {
    get {
    return saturationFilter?.value(forKey: "inputAmount") as? CGFloat
    return layer.sublayers?.last?.opacity
    }
    set {
    saturationFilter?.setValue(newValue, forKey: "inputAmount")
    layer.sublayers?.last?.opacity = newValue ?? 0
    }
    }

    var scale: CGFloat? {
    get {
    return filterLayer?.value(forKey: "scale") as? CGFloat
    }
    set {
    filterLayer?.setValue(newValue, forKey: "scale")
    }
    }
    }

    func animateScale() {
    effectView.filterLayer?.removeAllAnimations()
    effectView.enableSaturation = false
    effectView.enableBlur = false

    let anim = CABasicAnimation(keyPath: "scale")
    anim.fromValue = 0.05
    anim.toValue = 1
    anim.duration = 5
    anim.repeatCount = .infinity
    effectView.scale = 1
    effectView.filterLayer?.add(anim, forKey: "scale")
    }

    func animateBlur() {
    effectView.filterLayer?.removeAllAnimations()

    effectView.enableSaturation = false
    effectView.scale = 1
    effectView.enableBlur = false

    CATransaction.begin()
    CATransaction.setAnimationDuration(5)
    var anim = CABasicAnimation(keyPath: "filters.gaussianBlur.inputRadius")
    anim.fromValue = 30
    anim.toValue = 0
    anim.repeatCount = .infinity
    effectView.filterLayer?.add(anim, forKey: "filters.gaussianBlur.inputRadius")

    anim = CABasicAnimation(keyPath: "opacity")
    anim.fromValue = 1
    anim.toValue = 0
    anim.repeatCount = .infinity
    effectView.layer.sublayers?.last?.add(anim, forKey: "opacity")
    CATransaction.commit()
    }

    func animateBlurUIKit() {
    effectView.filterLayer?.removeAllAnimations()

    UIView.animate(withDuration: 5, delay: 0, options: .repeat, animations: {
    effectView.effect = nil
    }, completion: nil)
    }

    func animateSaturation() {
    effectView.filterLayer?.removeAllAnimations()
    effectView.enableBlur = false
    effectView.scale = 1

    let anim = CABasicAnimation(keyPath: "filters.colorSaturate.inputAmount")
    anim.fromValue = 0
    anim.toValue = 1.8
    anim.duration = 5
    anim.repeatCount = .infinity
    effectView.saturationAmount = 1.8
    effectView.filterLayer?.add(anim, forKey: "filters.colorSaturate.inputAmount")
    }

    effectView.enableSaturation = false
    effectView.scale = 0.5
    effectView.blurRadius = 5

    //animateScale()
    //animateBlur()
    //animateBlurUIKit()
    //animateSaturation()
    }
  4. @ilyapuchka ilyapuchka revised this gist Jan 20, 2017. 1 changed file with 0 additions and 15 deletions.
    15 changes: 0 additions & 15 deletions UIVisualEffect.swift
    Original file line number Diff line number Diff line change
    @@ -35,12 +35,6 @@ extension UIVisualEffectView {
    .first(where: { $0.value(forKey: "name") as? String == "colorSaturate" })
    }

    fileprivate var matrixFilter: NSObject? {
    return filterLayer?
    .filters?.flatMap({ $0 as? NSObject })
    .first(where: { $0.value(forKey: "name") as? String == "colorMatrix" })
    }

    var blurRadius: CGFloat? {
    get {
    return blurFilter?.value(forKey: kCIInputRadiusKey) as? CGFloat
    @@ -71,15 +65,6 @@ extension UIVisualEffectView {
    }
    }

    var enableColorMatrix: Bool {
    get {
    return matrixFilter?.value(forKey: "enabled") as? Bool ?? false
    }
    set {
    matrixFilter?.setValue(newValue, forKey: "enabled")
    }
    }

    var saturationAmount: CGFloat? {
    get {
    return saturationFilter?.value(forKey: "inputAmount") as? CGFloat
  5. @ilyapuchka ilyapuchka revised this gist Jan 20, 2017. 1 changed file with 0 additions and 23 deletions.
    23 changes: 0 additions & 23 deletions UIVisualEffect.swift
    Original file line number Diff line number Diff line change
    @@ -17,29 +17,6 @@ imageView.addSubview(effectView)
    PlaygroundPage.current.liveView = imageView
    PlaygroundPage.current.needsIndefiniteExecution = true


    func properties(_ instance: NSObject) {
    var count = UInt32()
    let classToInspect = type(of: instance)
    let properties : UnsafeMutablePointer<objc_property_t?> = class_copyPropertyList(classToInspect, &count)
    var propertyNames = [String]()
    let intCount = Int(count)
    for i in 0..<intCount {
    let property : objc_property_t = properties[i]!
    guard let propertyName = NSString(utf8String: property_getName(property)) as? String else {
    debugPrint("Couldn't unwrap property name for \(property)")
    break
    }

    let v = instance.value(forKey: propertyName)
    print(v!)
    propertyNames.append(propertyName)
    }

    free(properties)
    print(propertyNames)
    }

    extension UIVisualEffectView {

    fileprivate var filterLayer: CALayer? {
  6. @ilyapuchka ilyapuchka revised this gist Jan 20, 2017. 1 changed file with 4 additions and 4 deletions.
    8 changes: 4 additions & 4 deletions UIVisualEffect.swift
    Original file line number Diff line number Diff line change
    @@ -181,11 +181,11 @@ func animateSaturation() {
    effectView.filterLayer?.add(anim, forKey: "filters.colorSaturate.inputAmount")
    }

    effectView.enableSaturation = false
    effectView.scale = 0.5
    effectView.blurRadius = 5

    //animateScale()
    //animateBlur()
    //animateBlurUIKit()
    //animateSaturation()

    effectView.enableSaturation = false
    effectView.scale = 0.5
    effectView.blurRadius = 5
  7. @ilyapuchka ilyapuchka created this gist Jan 20, 2017.
    191 changes: 191 additions & 0 deletions UIVisualEffect.swift
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,191 @@
    //: Playground - noun: a place where people can play

    import UIKit
    import PlaygroundSupport
    import ObjectiveC

    let image = UIImage(named: "berlinerdom.jpg")!
    let imageView = UIImageView(image: image)
    imageView.frame.size.width = 540
    imageView.frame.size.height = 363
    let effectView = UIVisualEffectView(effect: UIBlurEffect(style: .light))
    effectView.frame.size.width = 540//360
    effectView.frame.size.height = 363//242
    effectView.center = imageView.center
    imageView.addSubview(effectView)

    PlaygroundPage.current.liveView = imageView
    PlaygroundPage.current.needsIndefiniteExecution = true


    func properties(_ instance: NSObject) {
    var count = UInt32()
    let classToInspect = type(of: instance)
    let properties : UnsafeMutablePointer<objc_property_t?> = class_copyPropertyList(classToInspect, &count)
    var propertyNames = [String]()
    let intCount = Int(count)
    for i in 0..<intCount {
    let property : objc_property_t = properties[i]!
    guard let propertyName = NSString(utf8String: property_getName(property)) as? String else {
    debugPrint("Couldn't unwrap property name for \(property)")
    break
    }

    let v = instance.value(forKey: propertyName)
    print(v!)
    propertyNames.append(propertyName)
    }

    free(properties)
    print(propertyNames)
    }

    extension UIVisualEffectView {

    fileprivate var filterLayer: CALayer? {
    return layer.sublayers?.first
    }

    fileprivate var blurFilter: NSObject? {
    return filterLayer?
    .filters?.flatMap({ $0 as? NSObject })
    .first(where: { $0.value(forKey: "name") as? String == "gaussianBlur" })
    }

    fileprivate var saturationFilter: NSObject? {
    return filterLayer?
    .filters?.flatMap({ $0 as? NSObject })
    .first(where: { $0.value(forKey: "name") as? String == "colorSaturate" })
    }

    fileprivate var matrixFilter: NSObject? {
    return filterLayer?
    .filters?.flatMap({ $0 as? NSObject })
    .first(where: { $0.value(forKey: "name") as? String == "colorMatrix" })
    }

    var blurRadius: CGFloat? {
    get {
    return blurFilter?.value(forKey: kCIInputRadiusKey) as? CGFloat
    }
    set {
    blurFilter?.setValue(newValue, forKey: kCIInputRadiusKey)
    }
    }

    var enableBlur: Bool {
    get {
    let dimLayer = layer.sublayers?.last?.opacity != 0
    return blurRadius != 0 && dimLayer
    }
    set {
    blurRadius = 0
    layer.sublayers?.last?.opacity = newValue ? 1 : 0
    }
    }

    /// the same as saturation amount 1
    var enableSaturation: Bool {
    get {
    return saturationFilter?.value(forKey: "enabled") as? Bool ?? false
    }
    set {
    saturationFilter?.setValue(newValue, forKey: "enabled")
    }
    }

    var enableColorMatrix: Bool {
    get {
    return matrixFilter?.value(forKey: "enabled") as? Bool ?? false
    }
    set {
    matrixFilter?.setValue(newValue, forKey: "enabled")
    }
    }

    var saturationAmount: CGFloat? {
    get {
    return saturationFilter?.value(forKey: "inputAmount") as? CGFloat
    }
    set {
    saturationFilter?.setValue(newValue, forKey: "inputAmount")
    }
    }

    var scale: CGFloat? {
    get {
    return filterLayer?.value(forKey: "scale") as? CGFloat
    }
    set {
    filterLayer?.setValue(newValue, forKey: "scale")
    }
    }
    }

    func animateScale() {
    effectView.filterLayer?.removeAllAnimations()
    effectView.enableSaturation = false
    effectView.enableBlur = false

    let anim = CABasicAnimation(keyPath: "scale")
    anim.fromValue = 0.05
    anim.toValue = 1
    anim.duration = 5
    anim.repeatCount = .infinity
    effectView.scale = 1
    effectView.filterLayer?.add(anim, forKey: "scale")
    }

    func animateBlur() {
    effectView.filterLayer?.removeAllAnimations()

    effectView.enableSaturation = false
    effectView.scale = 1
    effectView.enableBlur = false

    CATransaction.begin()
    CATransaction.setAnimationDuration(5)
    var anim = CABasicAnimation(keyPath: "filters.gaussianBlur.inputRadius")
    anim.fromValue = 30
    anim.toValue = 0
    anim.repeatCount = .infinity
    effectView.filterLayer?.add(anim, forKey: "filters.gaussianBlur.inputRadius")

    anim = CABasicAnimation(keyPath: "opacity")
    anim.fromValue = 1
    anim.toValue = 0
    anim.repeatCount = .infinity
    effectView.layer.sublayers?.last?.add(anim, forKey: "opacity")
    CATransaction.commit()
    }

    func animateBlurUIKit() {
    effectView.filterLayer?.removeAllAnimations()

    UIView.animate(withDuration: 5, delay: 0, options: .repeat, animations: {
    effectView.effect = nil
    }, completion: nil)
    }

    func animateSaturation() {
    effectView.filterLayer?.removeAllAnimations()
    effectView.enableBlur = false
    effectView.scale = 1

    let anim = CABasicAnimation(keyPath: "filters.colorSaturate.inputAmount")
    anim.fromValue = 0
    anim.toValue = 1.8
    anim.duration = 5
    anim.repeatCount = .infinity
    effectView.saturationAmount = 1.8
    effectView.filterLayer?.add(anim, forKey: "filters.colorSaturate.inputAmount")
    }

    //animateScale()
    //animateBlur()
    //animateBlurUIKit()
    //animateSaturation()

    effectView.enableSaturation = false
    effectView.scale = 0.5
    effectView.blurRadius = 5