Code to kill the leak

Anurag Pandit
2 min readFeb 5, 2020

--

clicked by isnt.love

Today, I’m going to talk about a common problem which at some point of time we all may have faced. And as title suggests it’s about the leak, so let’s explore this.

Recently, while working on a project I came across a requirement where we need to show a badge on certain View at certain logic.

For those who don’t know what is badge?

In simpler words: Badge is used to represent unread informations, it has a appearance of a dot kind, with a background colour, which may or may not have number inside it.

So sounds simple right?

My initial thought was like: Alright! just need to add a red dot on the view. After completing every aspect of it when I ran the code it all looked good.
At first!!!
However, looking closely at the added badge I found out the badge is leaking it’s colour!!!

Wait! what!

It’s a simple thing with yet simpler line of codes, what went wrong?

I re-checked the code, but no — all the bits & pieces were well written and correctly placed. For once I thought,
“oh!!! may be running on real device rather than simulator could solve this.”
But result was no different.

After spending a good amount of time, I plumbed a piece of code which had fixed this leak, I called it the masking effect. Let me show you how I did it, Let’s jump straight to code now:

 //
// set the frames,
// border-width of your requirement
//
let badgeSize: CGFloat = 10
let redBadge = UIView(frame:
CGRect(x: view.center.x,
y:view.center.y,
width: badgeSize,
height: badgeSize))
redBadge.layer.borderColor = UIColor.white.cgColor
redBadge.layer.borderWidth = 2
redBadge.backgroundColor = .red
redBadge.layer.cornerRadius = badgeSize * 0.5
redBadge.clipsToBounds = true
redBadge.layer.masksToBounds = true
redBadge.maskLayerOnView(radius: badgeSize * 0.5)
view.addSubview(redBadge)

We have done the basic setup here. The key here is maskLayerOnView . It’s not UIView’s method, I wrote an extension on UIView, which will take the radius for our path to address the leak of border colour.

extension UIView{ func maskLayerOnView(radius: CGFloat){
let maskLayer = CAShapeLayer()
maskLayer.path = UIBezierPath(roundedRect: self.bounds,
byRoundingCorners: [.allCorners],
cornerRadii: CGSize(width: radius,
height: radius)).cgPath
self.layer.mask = maskLayer
}
}

Here, we have used CAShapeLayer to create a path by UIBezier, it returns an immutable CGPathRef which is only valid until the UIBezierPath is further mutated. Setting the path will create an immutable copy of the provided CGPathRef, so any further mutations on a provided CGMutablePathRef will be ignored. And hence the leak is killed.

Try it out and send your feedbacks, feel free to comment for more optimised solution.

--

--