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 www.linkedin.com/in/Muhammad-Abubakar-iOS

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

Recommended from Medium

Azure App Configuration for Mobile Apps

The Azure App Configuration service dialog; the text in the dialog says “Create an app configuration to manage application settings in a centralized manner.”

Swift Control Flow With When-Then-Else

YouTube ends picture-in-picture iOS test for Premium subscribers : Gadget Game News

How do use foregroundStyle to apply gradients to SwiftUI views?

conic.gradient.intro.png

Understanding the UIViewController Lifecycle in iOS

SwiftUI: Scroll like in UIKit using only SwiftUI _hidden APIs

ADDING TESTS TO PROJECT WITH MODULAR ARCHITECTURE

Top hidden feature of iOS 14

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 www.linkedin.com/in/Muhammad-Abubakar-iOS

More from Medium

Creating SwiftUI views with two equal column spaces

How to convert .ogg/.oga audio into .wav in Swift using C++, Objective-C and Swift Package Manager

Async/Await & Actors in Swift

async/await

Some Notes when Upgrading into Xcode 13