How to draw blur shape using UIPanGestureRecognizer — Swift 5

If you are editing an image and you want to blur only specific part of image wether it is the sensitive info or the unwanted info, this article will help you to achieve this goal. After reading this article, you ll be able to draw a blur shape rectangle using UIPanGestureRecognizer.

Desired result image

We’ ll start off by making a Rectangle class, and we will define some properties inside that class.

class Rectangle: UIView { var color: UIColor = .clear {  didSet {   backgroundColor = color  } } var borderColor: CGColor = UIColor.lightGray.cgColor {  didSet {   layer.borderColor = borderColor  } } var borderWidth : CGFloat = 0.5 {  didSet {   layer.borderWidth = borderWidth  } }}

We’ ll also override draw(_ rect: CGRect) function so that we can draw our rectangle. Also, we will add a UIPanGestureRecognizer named moveRectangleGesture(_ gesture: UIPanGestureRecognizer) so that we can move the added blur to our desired position.

override func draw(_ rect: CGRect) {  layer.borderColor = self.borderColor  layer.borderWidth = self.borderWidth}override func didMoveToSuperview() {  addGestureRecognizer(UIPanGestureRecognizer(target: self, action:    #selector(moveRectangleGesture(_:))))}@objc func moveRectangleGesture(_ gesture: UIPanGestureRecognizer) {  frame.origin += gesture.translation(in: self)  gesture.setTranslation(.zero, in: self)}

Notice that we are using += inside the moveRectangleGesture(_ gesture: UIPanGestureRecognizer) function. We are overloading the += operator so that we can assign gesture translation to our drawn rectangle.

extension CGPoint { static func +=(lhs: inout CGPoint, rhs: CGPoint) {  lhs.x += rhs.x  lhs.y += rhs.y }}

Now that we are done with making Rectangle class, its time to draw blur using UIPanGestureRecognizer. We will declare an UIImageView inside our class and will give it proper frame. After that we will assign a pan gesture to that imageView.

class EditImageController : UIViewController { lazy var imageToEdit : UIImageView = {  let v = UIImageView(image:  "myImage")  v.frame = CGRect(x: 150, y: 500, width: 200, height: 200)  v.isUserInteractionEnabled = true  v.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(pan(_:))))  return v }()var allRectangles: [Rectangle] = []override func viewDidLoad() { super.viewDidLoad() view.addSubview(imageToEdit)} @objc func pan(_ gesture: UIPanGestureRecognizer) { }}

We’ve declared a class which have an image which on which we will draw our blur. On that image , we’ve added a panGesture. Also, we’ve declared an array of allRectangles which is of type Rectangle, to draw multiple blurs. Let’s complete the code for our panGesture.

@objc func pan(_ gesture: UIPanGestureRecognizer) { switch gesture.state {  case .began:   let rectangle = Rectangle(frame: .init(origin:     gesture.location(in: view), size: .init(width: 0, height: 0)))   view.addSubview(rectangle)   allRectangles.append(rectangle)  case .changed:   let distance = gesture.translation(in: view)   let index = allRectangles.index(before: allRectangles.endIndex)   let frame = allRectangles[index].frame   allRectangles[index].frame = .init(origin: frame.origin, size: .init(width: frame.width + distance.x, height: frame.height + distance.y))   allRectangles[index].setNeedsDisplay()   gesture.setTranslation(.zero, in: view)  case .ended:   let index = allRectangles.index(before: allRectangles.endIndex)   addBlur(to: allRectangles[index])   break default:   break }}func addBlur(to View: UIView) { let blurEffect = UIBlurEffect(style: .regular) let blurEffectView = UIVisualEffectView(effect: blurEffect) blurEffectView.frame = View.bounds blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight] View.addSubview(blurEffectView)}

Inside pan(_ gesture: UIPanGestureRecognizer), on .begin state we are creating a rectangle which has no width and height and we are appending it to the rectangles array. Then on .changed state, we are expanding the created rectangle frame along with the movement of our pan gesture. And finally upon .ended state, we add blur to our rectangle.

Adding blur through panGesture can be really helpful when are not sure how much part of an image we want to blur and when the parts to be blurred are not even enough. Through the above approach, we can avoid those problems.

Happy Coding!




iOS Developer — Connect with me

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Modularity lifehacks on iOS

ScrollIntoView extension method for IWebDriver


Continuous Integration for Flutter Apps on iOS with Semaphore

Adding a Dolly Track to Cinemachine

Top hidden feature of iOS 14

Easily manage accessibility attributes and accessing UI elements with XCTest on iOS

Flutter Localization on the Fly

AR You Ready for the Future? Part 1: Getting Started with ARKit on iOS

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Abu Bäkr

Abu Bäkr

iOS Developer — Connect with me

More from Medium

You put a constraint on core data and your app bricked?

Create your own color picker in Swift

MVP Explained With a Simple iOS App

How to resolve the swiping right action when trying to navigate to a previous screen in iOS.