Skip to content

Instantly share code, notes, and snippets.

@lanserxt
Created January 22, 2020 11:43
Show Gist options
  • Save lanserxt/b7eb586178c12aad0e36e3255acd2a56 to your computer and use it in GitHub Desktop.
Save lanserxt/b7eb586178c12aad0e36e3255acd2a56 to your computer and use it in GitHub Desktop.
FMBlurable (Swift 5 update)
//
// FMBlurable.swift
// FMBlurable
//
// Created by SIMON_NON_ADMIN on 18/09/2015.
// Copyright © 2015 Simon Gladman. All rights reserved.
//
// Thanks to romainmenke (https://twitter.com/romainmenke) for hint on a larger sample...
import UIKit
protocol Blurable
{
var layer: CALayer { get }
var subviews: [UIView] { get }
var frame: CGRect { get }
var superview: UIView? { get }
func add(subview: UIView)
func removeFromSuperview()
func blur(radius: CGFloat)
func unBlur()
var isBlurred: Bool { get }
}
extension Blurable
{
func blur(radius: CGFloat)
{
if self.superview == nil
{
return
}
UIGraphicsBeginImageContextWithOptions(CGSize(width: frame.width, height: frame.height), false, 1)
guard let context = UIGraphicsGetCurrentContext() else { return }
layer.render(in: context)
guard let image = UIGraphicsGetImageFromCurrentImageContext() else { return }
UIGraphicsEndImageContext();
guard let blur = CIFilter(name: "CIGaussianBlur"),
let this = self as? UIView else
{
return
}
blur.setValue(CIImage(image: image), forKey: kCIInputImageKey)
blur.setValue(radius, forKey: kCIInputRadiusKey)
let ciContext = CIContext(options: nil)
guard let result = blur.value(forKey: kCIOutputImageKey) as? CIImage else { return }
let boundingRect = CGRect(x:0,
y: 0,
width: frame.width,
height: frame.height)
guard let cgImage = ciContext.createCGImage(result, from: boundingRect) else { return }
let filteredImage = UIImage(cgImage: cgImage)
let blurOverlay = BlurOverlay()
blurOverlay.frame = boundingRect
blurOverlay.image = filteredImage
blurOverlay.contentMode = UIView.ContentMode.left
if let superview = superview as? UIStackView,
let index = (superview as UIStackView).arrangedSubviews.firstIndex(of: this)
{
removeFromSuperview()
superview.insertArrangedSubview(blurOverlay, at: index)
}
else
{
blurOverlay.frame.origin = frame.origin
UIView.transition(from: this,
to: blurOverlay,
duration: 0.2,
options: UIView.AnimationOptions.curveEaseIn,
completion: nil)
}
objc_setAssociatedObject(this,
&BlurableKey.blurable,
blurOverlay,
objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
}
func unBlur()
{
guard let this = self as? UIView,
let blurOverlay = objc_getAssociatedObject(self as? UIView ?? UIView(), &BlurableKey.blurable) as? BlurOverlay else
{
return
}
if let superview = blurOverlay.superview as? UIStackView,
let index = (blurOverlay.superview as? UIStackView)?.arrangedSubviews.firstIndex(of: blurOverlay)
{
blurOverlay.removeFromSuperview()
superview.insertArrangedSubview(this, at: index)
}
else
{
this.frame.origin = blurOverlay.frame.origin
UIView.transition(from: blurOverlay,
to: this,
duration: 0.2,
options: UIView.AnimationOptions.curveEaseIn,
completion: nil)
}
objc_setAssociatedObject(this,
&BlurableKey.blurable,
nil,
objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
}
var isBlurred: Bool
{
return objc_getAssociatedObject(self as? UIView ?? UIView(), &BlurableKey.blurable) is BlurOverlay
}
}
extension UIView: Blurable
{
func add(subview: UIView) {
self.addSubview(subview)
}
}
class BlurOverlay: UIImageView
{
}
struct BlurableKey
{
static var blurable = "blurable"
}
@provmusic
Copy link

Cheers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment