Badge is displayed behind UIButton

475 Views Asked by At

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.

enter image description here

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!

2

There are 2 best solutions below

2
On BEST ANSWER

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)
1
On

Try putting your badge image after (below) the button in your xml.