I've created a custom class that adds a badge to a UIButton. The badge itself is a UIImageView. The button can have a different UI for each state; when the button is disabled it has a clear background, it shows a border and the title, as shown in the image below.
As you can see the badge is displayed behind the border, but I want to badge to be on top of it. I have tried to adjust the zPosition of the layer of the badge by setting it to e.g. 9999. I also tried to bring the badge to the front by using the bringSubviewToFront method. Both ways did not work. My code to add the badge to the button is this:
private func addBadgeImageToButton() {
// badgeImage is a string containing the imageName
guard badgeImage != nil else {
return
}
badgeImageView = UIImageView(image: UIImage(named: badgeImage!))
// This line merely adjusts the position of the UIImageView
badgeImageView!.frame = adjustedRectangleForBadge(initialSize: badgeImageView!.frame.size)
badgeImageView!.layer.zPosition = 9999
addSubview(badgeImageView!)
// This line does not seem to work
//self.bringSubviewToFront(badgeImageView!)
// Adding these two lines won't do the trick either
self.setNeedsLayout()
self.layoutIfNeeded()
}
Can anyone help me with this tiny problem? Any help is greatly appreciated!
This is expected behavior. The border is supposed to always be on top of all subviews. You can get the desired effect by instead adding a UIView
with a border on to the UIButton
and then adding the icon after it.
let borderView = UIView(frame: CGRect(x: 0, y: 0, width: self.frame.size.width, height: self.frame.size.height)
borderView.layer.cornerRadius = self.layer.cornerRadius
borderView.layer.borderColor = self.layer.borderColor
// Remove the border color from the button its self
self.layer.borderColor = UIColor.clear.cgColor
// Add the border view to fake the border being there
addSubview(borderView)
// Then add the imageView on top of that border view
addSubview(badgeImageView)