How to draw blur shape using UIPanGestureRecognizer — Swift 5

Abu Bäkr
3 min readMay 11, 2021

--

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!

--

--