Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I make UILabel display outlined text?

All I want is a one pixel black border around my white UILabel text.

I got as far as subclassing UILabel with the code below, which I clumsily cobbled together from a few tangentially related online examples. And it works but it's very, very slow (except on the simulator) and I couldn't get it to center the text vertically either (so I hard-coded the y value on the last line temporarily). Ahhhh!

void ShowStringCentered(CGContextRef gc, float x, float y, const char *str) {     CGContextSetTextDrawingMode(gc, kCGTextInvisible);     CGContextShowTextAtPoint(gc, 0, 0, str, strlen(str));     CGPoint pt = CGContextGetTextPosition(gc);      CGContextSetTextDrawingMode(gc, kCGTextFillStroke);      CGContextShowTextAtPoint(gc, x - pt.x / 2, y, str, strlen(str)); }   - (void)drawRect:(CGRect)rect{      CGContextRef theContext = UIGraphicsGetCurrentContext();     CGRect viewBounds = self.bounds;      CGContextTranslateCTM(theContext, 0, viewBounds.size.height);     CGContextScaleCTM(theContext, 1, -1);      CGContextSelectFont (theContext, "Helvetica", viewBounds.size.height,  kCGEncodingMacRoman);      CGContextSetRGBFillColor (theContext, 1, 1, 1, 1);     CGContextSetRGBStrokeColor (theContext, 0, 0, 0, 1);     CGContextSetLineWidth(theContext, 1.0);      ShowStringCentered(theContext, rect.size.width / 2.0, 12, [[self text] cStringUsingEncoding:NSASCIIStringEncoding]); } 

I just have a nagging feeling that I'm overlooking a simpler way to do this. Perhaps by overriding "drawTextInRect", but I can't seem to get drawTextInRect to bend to my will at all despite staring at it intently and frowning really really hard.

like image 870
Monte Hurd Avatar asked Jul 09 '09 10:07

Monte Hurd


People also ask

How do I change my UILabel text?

Changing the text of an existing UILabel can be done by accessing and modifying the text property of the UILabel . This can be done directly using String literals or indirectly using variables.

How do you make UILabel bold?

Double Click on Bold to select it, and then right click on it to see more options. Select font > Bold from that option. It should do the task.

How do you strikethrough in Swift?

Swift5 UILabel Extension.Change the text property to attributed and select the text and right click to get the font property. Click on the strikethrough.


2 Answers

I was able to do it by overriding drawTextInRect:

- (void)drawTextInRect:(CGRect)rect {    CGSize shadowOffset = self.shadowOffset;   UIColor *textColor = self.textColor;    CGContextRef c = UIGraphicsGetCurrentContext();   CGContextSetLineWidth(c, 1);   CGContextSetLineJoin(c, kCGLineJoinRound);    CGContextSetTextDrawingMode(c, kCGTextStroke);   self.textColor = [UIColor whiteColor];   [super drawTextInRect:rect];    CGContextSetTextDrawingMode(c, kCGTextFill);   self.textColor = textColor;   self.shadowOffset = CGSizeMake(0, 0);   [super drawTextInRect:rect];    self.shadowOffset = shadowOffset;  } 
like image 161
kprevas Avatar answered Oct 23 '22 18:10

kprevas


A simpler solution is to use an Attributed String like so:

Swift 4:

let strokeTextAttributes: [NSAttributedStringKey : Any] = [     NSAttributedStringKey.strokeColor : UIColor.black,     NSAttributedStringKey.foregroundColor : UIColor.white,     NSAttributedStringKey.strokeWidth : -2.0,     ]  myLabel.attributedText = NSAttributedString(string: "Foo", attributes: strokeTextAttributes) 

Swift 4.2:

let strokeTextAttributes: [NSAttributedString.Key : Any] = [     .strokeColor : UIColor.black,     .foregroundColor : UIColor.white,     .strokeWidth : -2.0,     ]  myLabel.attributedText = NSAttributedString(string: "Foo", attributes: strokeTextAttributes) 

On a UITextField you can set the defaultTextAttributes and the attributedPlaceholder as well.

Note that the NSStrokeWidthAttributeName has to be negative in this case, i.e. only the inner outlines work.

UITextFields with an outline using attributed texts

like image 21
Axel Guilmin Avatar answered Oct 23 '22 19:10

Axel Guilmin