UILabel Background Color Leaks to Border
Asked Answered
N

6

20

I'm creating a UILabel to which I set the background color and corner radius with the following code:

self.scoreLabel.backgroundColor = [UIColor DISRed];// custom red`
self.scoreLabel.layer.masksToBounds = YES;
self.scoreLabel.layer.cornerRadius = self.scoreLabel.frame.size.width/2;
self.scoreLabel.layer.borderWidth = 8.0;
self.scoreLabel.layer.borderColor = [[UIColor DISNavy] CGColor];

However the background's color seems to be leaking to the edge of the border (see image). Any ideas why? Any idea on how to fix it?

enter image description here

Nauseating answered 11/4, 2015 at 0:0 Comment(3)
"Any idea on how to fix it?" Well, you have to admit that so far you've taken the easy way out. You're using a built-in view subclass (UILabel) and you're letting simple-minded layer commands do all the work for you, and hoping for the best. If you want a number in a circle, why don't you draw a number in a circle? Yes, it takes a little more code, but now you're in total control of what the user will see.Reflection
i admit it, it is the easy way out. why would i try the hard way first? if there is no straight forward way to accomplish it with this approach, i will consider another option.Nauseating
You see, I think just drawing it is more straightforward.Reflection
F
8

I was also facing the same problem. It was a silly mistake. I always forget to tick clipToBounds in case of cornerRadius.

So, just ticking the Clip to Bounds for UILabel in Storyboard fixed my problem.

And yes, we need to keep the below code too:

label.layer.masksToBounds = true
France answered 24/11, 2017 at 9:49 Comment(0)
L
1

I created my own UILabel and background colour does not seem to be leaking.

  1. Write this in .h file of your project.

    UILabel *label;

  2. Write this in .m file of your project.

label=[[UILabel alloc]initWithFrame:CGRectMake(100, 300, 100, 100)];//Set frame of label in your viewcontroller.
    [label setBackgroundColor:[UIColor redColor]];//Set background color of label.
    [label setText:@"Label"];//Set text in label.
    [label setTextColor:[UIColor blackColor]];//Set text color in label.
    [label setTextAlignment:NSTextAlignmentCenter];//Set text alignment in label.
    [label.layer setCornerRadius:50.0];//Set corner radius of label to change the shape.
    [label.layer setBorderWidth:8.0f];//Set border width of label.
    [label setClipsToBounds:YES];//Set its to YES for Corner radius to work.
    [label.layer setBorderColor:[UIColor greenColor].CGColor];//Set Border color.
    [self.view addSubview:label];//Add it to the view of your choice.
Leishaleishmania answered 17/4, 2015 at 9:39 Comment(0)
O
1

I ran into the same problem with the UIButton's background color leaking around the edge of its border.

Instead of setting the UIButton background color on the UIButton, set it on the UIButton's layer.

Replace:

self.scoreLabel.backgroundColor = [UIColor DISRed];// custom red`

With this:

self.scoreLabel.layer.backgroundColor = [[UIColor DISRed] CGColor];// custom red`
Octane answered 25/7, 2015 at 15:56 Comment(2)
didn't fix it for me. :( Do you know what the root cause of the problem is?Homely
THIS DOESNT WORK!Intoxicated
P
1

For those who are still facing the issue of border color leaking out: Go through the below code, please note you will need to set frames & border width as per your requirement, I'm setting the position as view's center

 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)

Secondly, we need to write an extension on UIView

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
 }
}

This code snippet removes the border color separating out, one can replicate this behaviour on any kind of views.

For detailed explanation please see this article.

Polygynous answered 3/3, 2020 at 11:39 Comment(0)
M
0

It is probably anti aliasing issue. you can better fix it by adding a bezier path around the corners.

CAShapeLayer *subLayer = [[CAShapeLayer alloc] init];
[subLayer setFillColor:[UIColor clearColor].CGColor];
[subLayer setStrokeColor:[UIColor whiteColor].CGColor];
[subLayer setLineWidth:1.0];
[subLayer setPath:[UIBezierPath bezierPathWithRoundedRect:imageView.bounds cornerRadius:imageView.layer.cornerRadius].CGPath];
[imageView.layer addSublayer:subLayer];
Misalliance answered 30/12, 2016 at 10:29 Comment(0)
B
0

Well, a lot of answers...

I found the problem persists, as long as the UIViews background color is used and not the background color of the UIViews 'layer'. In addition, of course, masking needs to be enabled.

For a UICollectionViewCell subclass the code is:

- (void)prepare
{
    self.contentView.layer.backgroundColor = UIColor.redColor.CGColor;
    self.contentView.layer.cornerRadius = 25.0;
    self.contentView.layer.borderColor = UIColor.blackColor.CGColor;
    self.contentView.layer.borderWidth = 1.0;
    //Enable to optimize image views: self.contentView.layer.shouldRasterize = YES;
    //Enable to optimize image views: self.contentView.layer.rasterizationScale = UIScreen.mainScreen.scale;
    self.contentView.layer.masksToBounds = YES;
    self.contentView.clipsToBounds = YES;
}

To make the setting of the background color more comfortable and less error prone, some could add this:

/*
 setBackgroundColor:

 */
- (void)setBackgroundColor:(UIColor *)p_BackgroundColor
{
    super.backgroundColor = nil;
    self.contentView.layer.backgroundColor = p_BackgroundColor.CGColor;

    self.contentView.layer.masksToBounds = YES;
    self.contentView.clipsToBounds = YES;
}
Boudoir answered 30/3, 2020 at 10:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.