UILabel default kerning different from CATextLayer - iphone

I have a UILabel with the string 'LA'. I also have a CATextLayer with the same characters in an NSAttributedString assigned to its string property. The kerning in the UILabel is noticeably different from the CATextLayer. Here's the code.
- (void)viewDidLoad
{
[super viewDidLoad];
//
// UILabel
//
UILabel *label1 = [[UILabel alloc] initWithFrame:CGRectMake(20, 50, 280, 100)];
label1.text = #"LA";
label1.backgroundColor = [UIColor clearColor];
label1.font = [UIFont fontWithName:#"Futura" size:90.0];
[self.view addSubview:label1];
//
// CATextLayer
//
UILabel *label2 = [[UILabel alloc] initWithFrame:CGRectMake(20, 130, 280, 100)];
label2.backgroundColor = [UIColor clearColor];
CATextLayer *textLayer = [[CATextLayer alloc] init];
textLayer.frame = label2.layer.bounds;
textLayer.contentsScale = [[UIScreen mainScreen] scale];
[label2.layer addSublayer:textLayer];
NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:#"LA"];
CTFontRef aFont = CTFontCreateWithName((__bridge CFStringRef)#"Futura", 90.0, NULL);
[string addAttribute:(NSString*)kCTFontAttributeName value:(__bridge id)aFont range:NSMakeRange(0, [string length])];
textLayer.string = string;
[self.view addSubview:label2];
}
Here's an image of the results.
Why is the kerning different between these two methods and what am I doing wrong in the CATextLayer example?

UIKit generally uses WebKit for its text rendering (as visible in this crash log), most likely for performance reasons. If you really need super-precision then there are some custom UILabel reimplementations using CoreText as its back-end.
EDIT:
As of iOS7 this is no longer true since UILabel uses TextKit for its rendering which is based on CoreText as well.

you should add attribute to your NSMutableAttributedString.
For the kerning:
CGFloat characterspacing = 10.0f;
CFNumberRef num = CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt8Type,&characterspacing);
[string addAttribute:(id)kCTKernAttributeName value:(id)num range:NSMakeRange(0 , [string length])];
CFRelease(num);
If you also need the line spacing, or set LineBreadMode:
CTLineBreakMode linebreak = kCTLineBreakByCharWrapping;
CTParagraphStyleSetting linebreakStyle;
linebreakStyle.spec = kCTParagraphStyleSpecifierLineBreakMode;
linebreakStyle.valueSize = sizeof(linebreak);
linebreakStyle.value = &linebreak;
CTParagraphStyleSetting lineSpaceStyle;
CGFloat linespacing = self.linesSpacing;
lineSpaceStyle.spec = kCTParagraphStyleSpecifierLineSpacingAdjustment;
lineSpaceStyle.valueSize = sizeof(linespacing);
lineSpaceStyle.value =&linespacing;
CTParagraphStyleSetting settings[ ] ={linebreakStyle,lineSpaceStyle};
CTParagraphStyleRef style = CTParagraphStyleCreate(settings ,2);
[string addAttribute:(id)kCTParagraphStyleAttributeName value:(id)style range:NSMakeRange(0 , [string length])];
CFRelease(style);
At the end, may you need calculate the number of line(linenum) about your kerning,line spacing and LineBreakMode:
CTFramesetterRef myframesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)string);
CGMutablePathRef leftColumnPath = CGPathCreateMutable();
CGPathAddRect(leftColumnPath, NULL ,CGRectMake(0 , 0 , Lable.frame.size.width, MAXFLOAT));
CTFrameRef leftFrame = CTFramesetterCreateFrame(myframesetter,CFRangeMake(0, 0), leftColumnPath , NULL);
CFArrayRef lines = CTFrameGetLines(leftFrame);
linenum = (int)CFArrayGetCount(lines);
CFRelease(myframesetter);
CFRelease(leftFrame);
CGPathRelease(leftColumnPath);

Well Core Text is really different when compared to drawing strings using UIKit, probably because it comes from Core Foundation and not AppKit or UIKit. I do understand your requirements to use a label for doing the metrics hard job on a string. The only solution for me is to match the kerning of UILabel in the attributed string, unfortunately I don't know the exact value but you can use this property to change that value kCTKernAttributeName. You should pay attention also for the interline that could be not the same.
Forcing that value to the matching kerning you could have the correct behavior. If you want the opposite (match CT kerning) you should do some math an later apply to the label a UIEdgeInset to math the correct label.
Hope this helps.

Related

Sizing UITextView to its content isn't working

Here's the code for a UITextView that I want to size to the height of its content.
If I write the textView.frame height explicitly like:
textView.frame = CGRectMake(100, 12, 320, 458);
the textView sizes to it's content as expected.
If, however, I write it like the following. It doesn't even display although the NSLog statement says that there's a value to textView.contentSize.height
UITextView *textView = [[UITextView alloc] init];
textView.layer.borderWidth = 5.0f;
textView.layer.borderColor = [[UIColor redColor] CGColor];
textView.text = [item objectForKey:#"description"];
textView.frame = CGRectMake(100, 12, 320, textView.contentSize.height);
NSLog(#"%f textviewcontnet size", textView.contentSize.height);
textView.editable = NO;
[self.view addSubview:textView];
When I log the output of:
NSLog(#"%f textviewcontent size", textView.contentSize.height);
I get "458.000000 textviewcontent size"
thanks for any help
I'd suggest trying:
UITextView *textView = [[UITextView alloc] init];
textView.layer.borderWidth = 5.0f;
textView.layer.borderColor = [[UIColor redColor] CGColor];
textView.text = [item objectForKey:#"description"];
textView.frame = CGRectMake(100, 12, 320, 458);
textView.editable = NO;
[self.view addSubview:textView];
textView.frame = CGRectMake(100, 12, 320, textView.contentSize.height);
I've heard that textView.contentSize.height doesn't work until it's been added to a view (though that's not my experience). More importantly, I don't know how it would interpret textView.contentSize.height if it doesn't yet know what the width of the control is. So go ahead, set the initial frame, do addSubview and then readjust the size based upon textView.contentSize.height.
Quickly copied out of one of my projects:
AppDelegate *appDelegate;
CGSize textSize1, textSize2;
appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
textSize1 = [self.subjectLabel.text sizeWithFont:[appDelegate fontNormal] constrainedToSize:CGSizeMake(300.0f, 10000.0f) lineBreakMode:NSLineBreakByWordWrapping];
self.subjectLabel.frame = CGRectMake(10, 5, 300, textSize1.height);
textSize2 = [self.descriptionLabel.text sizeWithFont:[appDelegate fontNormal] constrainedToSize:CGSizeMake(300.0f, 10000.0f) lineBreakMode:NSLineBreakByWordWrapping];
self.descriptionLabel.frame = CGRectMake(10, 5 + textSize1.height + 5, 300, textSize2.height);
[appDelegate fontNormal] just returns a UIFont object, the one that I am using for all "normal" text items. Don't worry about that too much. But it is important that you use the same font that is used for the text view too.
My example is a bit easier because it is a UILable. That works with a text view too but you will have to consider the insects. Easy solution, just substract some "fuzzy offset" from the width compared to the frame width of your text view.

Overriding UILabel

I have to present the currency and the price in a UILabel. In one label, but using different font sizes. Now it looks like this:
... and I did it overriding drawTextInRect: like this:
- (void)drawTextInRect:(CGRect)rect{
CGSize textSize = [self.text sizeWithFont:self.font];
textSize.width -= textSize.width/12;
CGRect analogRect = CGRectMake(0, 0, textSize.width, self.frame.size.height);
CGPoint centrino = self.center;
self.frame = analogRect;
self.center = centrino;
NSString *currency = [self.text substringWithRange:NSMakeRange(0, 3)];
NSString *amount = [self.text substringWithRange:NSMakeRange(3, self.text.length - 3)];
self.text = currency;
self.textAlignment = UITextAlignmentLeft;
self.font = [UIFont fontWithName:#"Helvetica-Bold" size:30.];
self.baselineAdjustment = UIBaselineAdjustmentAlignBaselines;
[super drawTextInRect:analogRect];
self.text = amount;
self.textAlignment = UITextAlignmentRight;
self.font = [UIFont fontWithName:#"Helvetica-Bold" size:40.];
[super drawTextInRect:analogRect];
}
Nice, isn't it?
But I need to align the currency and the price at the bottom, like this:
As you can see, I need to force "EUR" to go lower, because its size is smaller and it's centered, so it looks higher.
Please suggest a way to do this.
Thanks in advance!
NOTE:
Using 2 different labels is not good for me. I gotta do it in a single label.
Two ideas: 1) Since you're subclassing UILabel, you could put a second label for the currency type within the subclass' implementation, and your view would still think there's only a single label. 2) Since the NDA is lifted today on iOS 6, I'll suggest taking a look at attributed strings. Oh, and +1 for writing 'a UILabel' and not 'an UILabel.'
Ok, guys, thanks to everybody for your fast answers, but I have no time for researches, so I have found a newbie solution.
I feel shame but here is it:
- (void)setCurrencyAndPrice{
//set the labels' texts
[label_currency setText:#"EUR"];
[label_amount setText:#"12.34"];
//set the sizes to fit the content
[label_currency sizeToFit];
[label_amount sizeToFit];
//read the new frame of the labels
CGRect curRect = label_currency.frame;
CGRect amoRect = label_amount.frame;
//adjust the position of the price to the top-right
[label_amount setFrame:CGRectMake(320 - amoRect.size.width - 10, 0, amoRect.size.width, amoRect.size.height)];
//read again the price frame
amoRect = label_amount.frame;
//stick the currency to the price, spacing 10 pixels
[label_currency setFrame:CGRectMake(amoRect.origin.x - curRect.size.width - 10, 11, curRect.size.width, curRect.size.height)];
}
As you can see, nothing to override, just using 2 different labels - exactly what I did NOT want to do, but the time runs faster that I am coding.
Cheers!
P.S.: Although I have found the solution for myself, I like #MichaelMangold' idea, so I accept his answer.
Instead of using two UILabels, you can have one label with multiple text fonts styles and colors. Here is an example, may be that might help you :
UILabel *customLbl = [[UILabel alloc] initWithFrame:CGRectMake(50, 100, 200, 25)];
customLbl.backgroundColor = [UIColor yellowColor];
[self createTwoTextStyleInSingleUILabel:customLbl];// custom method calling
[self.view addSubview:customLbl];
Custom Method goes like this :
Before applying this method, add QuartzCore framework (needed for CALayers), and CoreText framework(needed for the attributed string.) in your project.
#import <QuartzCore/QuartzCore.h>
#import <CoreText/CoreText.h>
- (void)createTwoTextStyleInSingleUILabel: (UILabel *) myLabel{
NSString *firstText = NSLocalizedString(#"First text:", nil);
NSString *secondText = [NSString stringWithFormat:#"%# %#",firstText,#"Second text"];
CATextLayer *myLabelTextLayer;
/* Create the text layer on demand */
if (!myLabelTextLayer) {
myLabelTextLayer = [[CATextLayer alloc] init];
myLabelTextLayer.backgroundColor = [UIColor clearColor].CGColor;
myLabelTextLayer.wrapped = NO;
CALayer *layer = myLabel.layer; //assign layer to your UILabel
myLabelTextLayer.frame = CGRectMake((layer.bounds.size.width-180)/2 + 10, (layer.bounds.size.height-30)/2 + 10, 180, 30);
myLabelTextLayer.contentsScale = [[UIScreen mainScreen] scale];
myLabelTextLayer.alignmentMode = kCAAlignmentCenter;
[layer addSublayer:myLabelTextLayer];
}
/* Create the attributes (for the attributed string) */
// customizing first string
CGFloat fontSize = 16;
UIFont *boldFont = [UIFont boldSystemFontOfSize:fontSize];
CTFontRef ctBoldFont = CTFontCreateWithName((__bridge CFStringRef)boldFont.fontName, boldFont.pointSize, NULL);
CGColorRef cgColor = [UIColor redColor].CGColor;
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
(__bridge id)ctBoldFont, (id)kCTFontAttributeName,
cgColor, (id)kCTForegroundColorAttributeName, nil];
CFRelease(ctBoldFont);
// customizing second string
UIFont *font = [UIFont systemFontOfSize:16];
CTFontRef ctFont = CTFontCreateWithName((__bridge CFStringRef)font.fontName, font.pointSize, NULL);
CGColorRef cgSubColor = [UIColor blackColor].CGColor;
NSDictionary *subAttributes = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge id)ctFont, (id)kCTFontAttributeName,cgSubColor, (id)kCTForegroundColorAttributeName, nil];
CFRelease(ctFont);
/* Create the attributed string (text + attributes) */
NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:secondText attributes:attributes];
float lengthOfSecondString = 12.0; // length of second string including blank space inbetween text, space in front , space after text.. Be careful, your app may crash here if length is beyond the second text length (lengthOfSecondString = text length + blank spaces)
[attrStr addAttributes:subAttributes range:NSMakeRange(firstText.length, lengthOfSecondString)];
// you can add another subattribute in the similar way as above , if you want change the third textstring style
/* Set the attributes string in the text layer :) */
myLabelTextLayer.string = attrStr;
myLabelTextLayer.opacity = 1.0; //to remove blurr effect
}
This library will work for you https://github.com/AliSoftware/OHAttributedLabel
I'd build a UIView subclass called ValueUnitsLabel. Give it two labels and let it control framing, font sizes etc. It can also be smart about reading NSLocale.

Is it possible to set different font in One UIlabel?

I have a string like "This is a good apple." to display on my UIlabel. I would like to set the word "good" with different font. Just look like "This is a good apple."
Take a look at NSAttributedString... Use OHAttributedLabel draw NSAttributedString because UILabel,UITextView doesnot support NSAttributedString...
PS: if you plan to distribute an iOS6 or newer application, as UILabel now support NSAttributedString, you should use UILabel directly instead of OHAttributedLabel as it is now natively supported by the OS.
There is a way to set different / multiple fonts & other properties on Label using NSMutableAttributedString.
Foll is my code:
UIFont *ArialFont = [UIFont fontWithName:#"arial" size:18.0];
NSDictionary *arialdict = [NSDictionary dictionaryWithObject: ArialFont forKey:NSFontAttributeName];
NSMutableAttributedString *AattrString = [[NSMutableAttributedString alloc] initWithString:title attributes: arialdict];
UIFont *VerdanaFont = [UIFont fontWithName:#"verdana" size:12.0];
NSDictionary *veradnadict = [NSDictionary dictionaryWithObject:VerdanaFont forKey:NSFontAttributeName];
NSMutableAttributedString *VattrString = [[NSMutableAttributedString alloc]initWithString: newsDate attributes:veradnadict];
[VattrString addAttribute:NSForegroundColorAttributeName value:[UIColor blackColor] range:(NSMakeRange(0, 15))];
[AattrString appendAttributedString:VattrString];
lblText.attributedText = AattrString;
Note that lblText is the UILabel, outlet as file owner.
One can keep on appending as many NSMutableAttributedString he wants..
Also Note that I've added verdana & arial font in my project & added a plist for the same.
This is not possible with UILabel. But you could use Core Text.
An other easier approach could be to use a very small UIWebView. In this you can set the font using html commands.
Im sorry but that's not possible with the UILabel implementation, you have two options:
You can create a UIWebView and put the text HTML formatted
You can make your own UILabel implementation with that functionallity, with, for example, Core Text
Instead of using two UILabels, you can have one label with multiple text fonts styles and colors. Here is an example :
UILabel *customLbl = [[UILabel alloc] initWithFrame:CGRectMake(50, 100, 200, 25)];
customLbl.backgroundColor = [UIColor yellowColor];
[self createTwoTextStyleInSingleUILabel:customLbl];// custom method calling
[self.view addSubview:customLbl];
Custom Method goes like this :
Before applying this method, add QuartzCore framework (needed for CALayers), and CoreText framework(needed for the attributed string.) in your project.
#import <QuartzCore/QuartzCore.h>
#import <CoreText/CoreText.h>
- (void)createTwoTextStyleInSingleUILabel: (UILabel *) myLabel{
NSString *firstText = NSLocalizedString(#"First text:", nil);
NSString *secondText = [NSString stringWithFormat:#"%# %#",firstText,#"Second text"];
CATextLayer *myLabelTextLayer;
/* Create the text layer on demand */
if (!myLabelTextLayer) {
myLabelTextLayer = [[CATextLayer alloc] init];
myLabelTextLayer.backgroundColor = [UIColor clearColor].CGColor;
myLabelTextLayer.wrapped = NO;
CALayer *layer = myLabel.layer; //assign layer to your UILabel
myLabelTextLayer.frame = CGRectMake((layer.bounds.size.width-180)/2 + 10, (layer.bounds.size.height-30)/2 + 10, 180, 30);
myLabelTextLayer.contentsScale = [[UIScreen mainScreen] scale];
myLabelTextLayer.alignmentMode = kCAAlignmentCenter;
[layer addSublayer:myLabelTextLayer];
}
/* Create the attributes (for the attributed string) */
// customizing first string
CGFloat fontSize = 16;
UIFont *boldFont = [UIFont boldSystemFontOfSize:fontSize];
CTFontRef ctBoldFont = CTFontCreateWithName((__bridge CFStringRef)boldFont.fontName, boldFont.pointSize, NULL);
CGColorRef cgColor = [UIColor redColor].CGColor;
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
(__bridge id)ctBoldFont, (id)kCTFontAttributeName,
cgColor, (id)kCTForegroundColorAttributeName, nil];
CFRelease(ctBoldFont);
// customizing second string
UIFont *font = [UIFont systemFontOfSize:16];
CTFontRef ctFont = CTFontCreateWithName((__bridge CFStringRef)font.fontName, font.pointSize, NULL);
CGColorRef cgSubColor = [UIColor blackColor].CGColor;
NSDictionary *subAttributes = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge id)ctFont, (id)kCTFontAttributeName,cgSubColor, (id)kCTForegroundColorAttributeName, nil];
CFRelease(ctFont);
/* Create the attributed string (text + attributes) */
NSMutableAttributedString *attrStr = [[NSMutableAttributedString alloc] initWithString:secondText attributes:attributes];
float lengthOfSecondString = 12.0; // length of second string including blank space inbetween text, space in front , space after text.. Be careful, your app may crash here if length is beyond the second text length (lengthOfSecondString = text length + blank spaces)
[attrStr addAttributes:subAttributes range:NSMakeRange(firstText.length, lengthOfSecondString)];
// you can add another subattribute in the similar way as above , if you want change the third textstring style
/* Set the attributes string in the text layer :) */
myLabelTextLayer.string = attrStr;
myLabelTextLayer.opacity = 1.0; //to remove blurr effect
}
Modified Akshay's answer and implemented it with Swift:
// First part with font size 10
let firstPartInfo = [NSFontAttributeName: UIFont.systemFontOfSize(10.0)]
var attributedString = NSMutableAttributedString(string: "First Part", attributes: firstPartInfo)
// Second part with font size 20
let secondPartInfo = [NSFontAttributeName: UIFont.systemFontOfSize(20.0)]
attributedString.appendAttributedString(
NSAttributedString(string: "Second Part", attributes: secondPartInfo))
// Lastly set the attributed text
label.attributedText = attributedString
No reason to use third party solutions or subclasses.

UILabel not aligning perfectly center when wrapping

See image for example: http://img25.imageshack.us/img25/6996/90754687.png
The grey background indicates the size of the UILabel frame.
For some reason, the first line of wrapped text doesn't seem to always center, even though I'm using UITextAlignmentCenter.
Here's the code I use to set up my labels:
self.titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
titleLabel.font = [UIFont boldSystemFontOfSize:fontHeight];
titleLabel.backgroundColor = [UIColor grayColor];
titleLabel.numberOfLines = 2;
titleLabel.lineBreakMode = UILineBreakModeMiddleTruncation;
NSString * title = file.name;
CGSize maximumSize = CGSizeMake(thumbnailWidth+4,fontHeight * 3);
UIFont * font = [UIFont boldSystemFontOfSize:12];
CGSize stringSize = [title sizeWithFont:font constrainedToSize:maximumSize lineBreakMode:titleLabel.lineBreakMode];
CGRect stringFrame = CGRectMake(0, thumbnailHeight + thumbnailPadding, thumbnailWidth + 4, stringSize.height);
titleLabel.text = title;
titleLabel.frame = stringFrame;
titleLabel.textAlignment = UITextAlignmentCenter;
Is that because there are no spaces in the text? In IB it appears to react just like your getting, if you have no spaces. Setting the line break mode to character wrap tends to center the second lines to the first, but that may not be entirely what you want either.

How to change an UILabel/UIFont's letter spacing?

I've searched loads already and couldn't find an answer.
I have a normal UILabel, defined this way:
UILabel *totalColors = [[[UILabel alloc] initWithFrame:CGRectMake(5, 7, 120, 69)] autorelease];
totalColors.text = [NSString stringWithFormat:#"%d", total];
totalColors.font = [UIFont fontWithName:#"Arial-BoldMT" size:60];
totalColors.textColor = [UIColor colorWithRed:221/255.0 green:221/255.0 blue:221/255.0 alpha:1.0];
totalColors.backgroundColor = [UIColor clearColor];
[self addSubview:totalColors];
And I wanted the horizontal spacing between letters, to be tighter, whilst mantaining the font size.
Is there a way to do this? It should be a pretty basic thing to do.
Cheers guys,
Andre
UPDATE:
So I was forced to do it like this:
- (void) drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSelectFont (context, "Arial-BoldMT", 60, kCGEncodingMacRoman);
CGContextSetCharacterSpacing (context, -10);
CGContextSetTextDrawingMode (context, kCGTextFill);
CGContextSetRGBFillColor(context, 221/255.0, 221/255.0, 221/255.0, 221/255.0);
CGAffineTransform xform = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, 0.0);
CGContextSetTextMatrix(context, xform);
char* result = malloc(17);
sprintf(result, "%d", totalNumber);
CGContextShowTextAtPoint (context, 0, 54, result, strlen(result));
}
But I need to align this to the right.
I could do that manually if I knew the width of the drawn text, but it's proving near impossible to find that.
I've read about ATSU, but I couldn't find any examples.
This sucks :/
From iOS 6 you can use NSAttributedString in UILabel.
In attributed string you can use attribute NSKernAttributeName to set letter spacing
NSMutableAttributedString* attrStr = [[NSMutableAttributedString alloc] initWithString: #"Test test test test "];
[attrStr addAttribute:NSKernAttributeName value:#(4.0) range:NSMakeRange(0, attrStr.length)];
UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(0, 300, 300, 100)];
label.attributedText = attrStr;
I've extended UILabel to change the character spacing. This should work out the box and pulls font, text, color etc from the UILabel itself (proper coding!).
You may notice I draw the text twice, first with clear color. This is to auto center the text in the label. Whilst this may be inefficient - isn't it nice to be auto centered?
Enjoy!
#interface RALabel : UILabel {
}
#end
#implementation RALabel
- (void) drawRect:(CGRect)rect
{
// Drawing code
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSelectFont (context, [self.font.fontName cStringUsingEncoding:NSASCIIStringEncoding], self.font.pointSize, kCGEncodingMacRoman);
CGContextSetCharacterSpacing(context, 1);
CGContextSetFillColorWithColor(context, [[UIColor clearColor] CGColor]);
CGAffineTransform myTextTransform = CGAffineTransformScale(CGAffineTransformIdentity, 1.f, -1.f );
CGContextSetTextMatrix (context, myTextTransform);
// draw 1 but invisbly to get the string length.
CGPoint p =CGContextGetTextPosition(context);
float centeredY = (self.font.pointSize + (self.frame.size.height- self.font.pointSize)/2)-2;
CGContextShowTextAtPoint(context, 0, centeredY, [self.text cStringUsingEncoding:NSASCIIStringEncoding], [self.text length]);
CGPoint v =CGContextGetTextPosition(context);
// calculate width and draw second one.
float width = v.x - p.x;
float centeredX =(self.frame.size.width- width)/2;
CGContextSetFillColorWithColor(context, [self.textColor CGColor]);
CGContextShowTextAtPoint(context, centeredX, centeredY, [self.text cStringUsingEncoding:NSASCIIStringEncoding], [self.text length]);
}
I've come up with a solution for the letter spacing and the alignment to the right.
Here it goes:
NSString *number = [NSString stringWithFormat:#"%d", total];
int lastPos = 85;
NSUInteger i;
for (i = number.length; i > 0; i--)
{
NSRange range = {i-1,1};
NSString *n = [number substringWithRange:range];
UILabel *digit = [[[UILabel alloc] initWithFrame:CGRectMake(5, 10, 35, 50)] autorelease];
digit.text = n;
digit.font = [UIFont fontWithName:#"Arial-BoldMT" size:60];
digit.textColor = [UIColor colorWithRed:221/255.0 green:221/255.0 blue:221/255.0 alpha:1.0];
digit.backgroundColor = [UIColor clearColor];
[self addSubview:digit];
CGSize textSize = [[digit text] sizeWithFont:[digit font]];
CGFloat textWidth = textSize.width;
CGRect rect = digit.frame;
rect.origin.x = lastPos - textWidth;
digit.frame = rect;
lastPos = rect.origin.x + 10;
}
The letter spacing is the "10" on the last line.
The alignment comes from the lastPos.
Hope this helps anyone out there.
In Swift:
let myTitle = "my title"
let titleLabel = UILabel()
let attributes: NSDictionary = [
NSFontAttributeName:UIFont(name: "HelveticaNeue-Light", size: 20),
NSForegroundColorAttributeName:UIColor.whiteColor(),
NSKernAttributeName:CGFloat(2.0)
]
let attributedTitle = NSAttributedString(string: myTitle, attributes: attributes as? [String : AnyObject])
titleLabel.attributedText = attributedTitle
titleLabel.sizeToFit()
Not in any publicly available version of iPhone OS. ;-) If you are a current iPhone Developer, you can get an idea of where iPhone OS is going by looking through the "What's New" notes for iPhone OS 3.2.
Update: iOS v3.2, which added support for kerning, was still under NDA when I posted this. For an update-to-date answer, see How to set kerning in iPhone UILabel.