Why Does Kerning fail for NSAttributedString in IOS7 - ios7

My app has a UILabel formatted as an NSAttributedString with
the attribute: 'NSKernAttributeName #1.9,'
When the below code is compiled on iPad running IOS6, the kern works as expected.
When compiled on iPad running IOS7, no kerning occurs.
I have filed Bug at Apple Developer site. #15108371 - No Response yet
NSString *formattedNumber;
NSNumber *scoreNum = [[NSNumber alloc] initWithLongLong:thisScore];
NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init];
formatter.numberStyle = NSNumberFormatterPadBeforeSuffix;
formatter.formatWidth = 10;
formatter.paddingCharacter = #"0";
formatter.numberStyle = NSNumberFormatterDecimalStyle;
formatter.usesGroupingSeparator = NO;
formattedNumber = [formatter stringFromNumber:scoreNum];
//Creat atributed string of formated number.
NSShadow *textShadow = [[NSShadow alloc] init];
textShadow.shadowColor = [UIColor colorWithRed:0.5 green:0.7 blue:1 alpha:1.0];
textShadow.shadowBlurRadius = 5.0;
textShadow.shadowOffset = CGSizeMake(0,0);
NSAttributedString *pHighScoreStyle = [[NSAttributedString alloc] initWithString:formattedNumber attributes: #{
NSFontAttributeName: [UIFont fontWithName:#"courier" size:16],
NSForegroundColorAttributeName: [UIColor colorWithRed:0.6 green:0.8 blue:1.0 alpha:0.8],
NSKernAttributeName: #1.9,
NSShadowAttributeName: textShadow } ];
//Change the disply value.
runningScore.attributedText = pHighScoreStyle;

OK. I had the same problem (see comment above). It depends on the font (I used Courier as well). For some strange reason Courier does not support kerning (in iOS7!). Use CourierNewPSMT and everything works as expected .... at least for me.
BTW: Here is a nice list of fonts on the iphone:
http://iosfonts.com/

Related

Objective C label line spacing?

Is there a way to set the distance of two lines within a UILabel?
I tried to do it within Interface Builder but without success.
The code you want will be something like this:
NSMutableAttributedString* attrString = [[NSMutableAttributedString alloc] initWithString:#"Sample text"];
NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init];
[style setLineSpacing:24];
[attrString addAttribute:NSParagraphStyleAttributeName
value:style
range:NSMakeRange(0, strLength)];
uiLabel.attributedText = attrString;
You can use NSAttributedString to add spacing between two lines within a UILabel:
NSString *labelText = #"My String";
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:labelText];
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
[paragraphStyle setLineSpacing:20];
[attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, [labelText length])];
cell.label.attributedText = attributedString ;
OR
If you are using storyboard then you can control line spacing in the storyboard by selecting text type is attributed and add spacing value:
Since iOS 6, Apple added NSAttributedString to UIKit, making it possible to use NSParagraphStyle to change the line spacing.
Alternatively, you can do this via Storyboards using Attributed Text and then clicking the ... symbol. See link below for screenshot.
https://i.stack.imgur.com/aiNfR.png

Justify text for UILabel in iOS 9

I have found solution to justify text in UILabel for versions up to iOS 8.4 through attributed strings: set label string as attributed and modify hyphenation value as presented below.
This solution stopped working on iOS 9 (text shows left aligned). I need other working solution which supports from iOS 7 or at least works at iOS 9 (would add 'if' somewhere)
Update:
It seems that adding a #"locale" key to attributes of NSAttributedString may help. See here.
Original answer:
You can always use NSAttributedString here:
NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
paragraphStyle.hyphenationFactor = 1;
paragraphStyle.alignment = NSTextAlignmentJustified;
NSDictionary *attributes = #{
NSFontAttributeName: [UIFont preferredFontForTextStyle:UIFontTextStyleBody],
NSParagraphStyleAttributeName: paragraphStyle
};
NSString *string = #"your text here";
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:string attributes:attributes];
self.label.attributedText = attributedString;
self.label.numberOfLines = 0;

Core plot: annotation with text and image

I would like to add an annotation to my graph composed by a text and an image like this:
I can already display the text ("13" in the picture) but I'm not able to add the image below the text.
I've tried with CPTLayer, CPTBorderedLayer,..., but not of them work as expected.
Here is the code I'm using to display the text:
NSNumber *valueToDisplay = [NSNumber numberWithInt:13];
NSString *valueToDisplayString = [formatter stringFromNumber:valueToDisplay];
CPTTextLayer *textLayer = [[CPTTextLayer alloc] initWithText:valueToDisplayString style:style];
self.priceAnnotation.contentLayer = textLayer;
self.priceAnnotation.anchorPlotPoint = [NSArray arrayWithObjects:[NSNumber numberWithFloat:7.0], [NSNumber numberWithFloat:14.0], nil];
[self.graph.plotAreaFrame.plotArea addAnnotation:self.priceAnnotation];
How can I add the image below the text value ?
This is one of the pieces of code I've tried:
CPTBorderedLayer *immagine = [[CPTBorderedLayer alloc] initWithFrame:CGRectMake(0, 0, 77, 36)];
CPTFill *fillImage = [CPTFill fillWithImage:[CPTImage imageWithCGImage:[[UIImage imageNamed:#"sfondoStima.png"] CGImage]]];
immagine.fill = fillImage;
self.imageAnnotation.contentLayer = immagine;
self.imageAnnotation.anchorPlotPoint = [NSArray arrayWithObjects:[NSNumber numberWithFloat:7.0], [NSNumber numberWithFloat:5.0], nil];
[self.graph.plotAreaFrame.plotArea addAnnotation:self.imageAnnotation];
But this is the result: the bitmap (77x36) is for some reason much bigger than what it should be:
Please give me some help ... I've already tried different tutorial/example I've found but none of them seems to work.
Thanks,
Corrado
CPTTextLayer is a subclass of CPTBorderedLayer. For a simple background like this, I wouldn't bother with an image at all. I'd try something like this (untested):
CPTMutableLineStyle lineStyle = [CPTMutableLineStyle lineStyle];
lineStyle.lineWidth = 2.0;
lineStyle.lineColor = [CPTColor whiteColor];
CPTTextLayer *textLayer = [[CPTTextLayer alloc] initWithText:valueToDisplayString style:style];
textLayer.fill = [CPTFill fillWithColor:[CPTColor blueColor]];
textLayer.cornerRadius = 10.0;
textLayer.borderLineStyle = lineStyle;
Set the padding on the textLayer to control the space between the border line and the text.
If you have more complex needs that requires an image, be sure to set the image scale correctly. [CPTImage imageNamed:] does this for you.

Cocoa NSTextField line spacing

I'm struggling with a very simple problem, I've several NSTextField ( I can't use NSTextView right now) and I need to change the line spacing of the displayed text.
What can I do to reduce row height or line spacing? Shrinking the font size isn't an option.
Any help would be really appreciated!
Have a great weekend,
!)
For reference you want to read this description of paragraph styles: Cocoa Paragraph Styles and note that everything in there is additional space added between lines, between paragraphs, before paragraphs, etc. You can set the values in your NSMutableParagraphStyle to zero but no lower.
To further shrink the spacing between lines, use setMaximumLineHeight, thanks to "6 1" for the code (I've add the setMaximumLineHeight):
NSString *title = #"title here";
NSFont *bold14 = [NSFont boldSystemFontOfSize:14.0];
NSColor *textColor = [NSColor redColor];
NSMutableParagraphStyle *textParagraph = [[NSMutableParagraphStyle alloc] init];
[textParagraph setLineSpacing:10.0]; // this sets the space BETWEEN lines to 10points
[textParagraph setMaximumLineHeight:12.0]; this sets the MAXIMUM height of the lines to 12points
NSDictionary *attrDic = [NSDictionary dictionaryWithObjectsAndKeys:bold14, NSFontAttributeName, textColor, NSForegroundColorAttributeName, textParagraph, NSParagraphStyleAttributeName, nil];
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:title attributes:attrDic];
[self.titleField setAllowsEditingTextAttributes:YES];
[self.titleField setAttributedStringValue:attrString];
Swift version of Jason Harrison's excellent Obj-c answer:
let title:String = "title here"
let bold14:NSFont = NSFont.boldSystemFontOfSize(14.0)
let textColor:NSColor = NSColor.redColor()
let textParagraph:NSMutableParagraphStyle = NSMutableParagraphStyle()
textParagraph.lineSpacing = 10.0 /*this sets the space BETWEEN lines to 10points*/
textParagraph.maximumLineHeight = 12.0/*this sets the MAXIMUM height of the lines to 12points*/
let attribs = [NSFontAttributeName:bold14,NSForegroundColorAttributeName:textColor,NSParagraphStyleAttributeName:textParagraph]
let attrString:NSAttributedString = NSAttributedString.init(string: title, attributes: attribs)
textField.attributedStringValue = attrString
you can use NSAttributedString to show the text.
NSFont *bold14 = [NSFont boldSystemFontOfSize:14.0];
NSColor *textColor = [NSColor redColor];
NSMutableParagraphStyle *textParagraph = [[NSMutableParagraphStyle alloc] init];
[textParagraph setLineSpacing:10.0];
NSDictionary *attrDic = [NSDictionary dictionaryWithObjectsAndKeys:bold14, NSFontAttributeName, textColor, NSForegroundColorAttributeName, textParagraph, NSParagraphStyleAttributeName, nil];
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:title attributes:attrDic];
[self.titleField setAllowsEditingTextAttributes:YES];
[self.titleField setAttributedStringValue:attrString];
It's ok to display text not for inputing text. And I only know how to set line spacing.

Cocoa get string width in pixels from font

I am trying to find the width in pixels of a string from the font and font size. I am currently using this code, but it is not working 100% of the time. Is there another way to do it?
NSSize textSize = [aTextLayer.string sizeWithAttributes:[NSDictionary dictionaryWithObjectsAndKeys:#"Bank Gothic Medium", NSFontNameAttribute, [NSNumber numberWithFloat:aTextLayer.fontSize], NSFontSizeAttribute, nil]];
NSAttributedString is granted a -size method by the Application Kit Additions.
NSDictionary* attributes = [NSDictionary dictionaryWithObjectsAndKeys:
#"Bank Gothic Medium", NSFontNameAttribute,
[NSNumber numberWithFloat:aTextLayer.fontSize], NSFontSizeAttribute,
nil];
NSAttributedString* attributedString = [[NSAttributedString alloc] initWithString:aTextLayer.string attributes:attributes];
NSSize size = attributedString.size;
Here is what i use to get the size of a string...
NSSize size = [#"Some text" sizeWithAttributes:[NSDictionary dictionaryWithObject:[NSFont fontWithName:#"Helvetica Neue Bold" size:24.0f] forKey:NSFontAttributeName]];
NOTE: If you are adding the string to a textfield, i have found that you need to add about 10 to size.width for it to fit.
Try using the actual NSFont (or UIFont) object instead of just the name of the font.
Here is yet another example:
NSString *test = [[NSString alloc] initWithFormat:#"%u:%u:%u.000", hours, minutes, seconds];
NSSize boundingSize = {100,300}; //I suppose this is the constraints?
NSRect boundingRect = [test boundingRectWithSize:boundingSize options:NULL attributes:stringAttributes];
point.x -= boundingRect.size.width; //This point points at the end of screen
[test drawAtPoint:point withAttributes:stringAttributes];
Here is for the stringAttributes, that may help noobs like me:
NSMutableDictionary *stringAttributes;
stringAttributes = [NSMutableDictionary dictionary];
[stringAttributes setObject:[NSFont fontWithName:#"Monaco" size:16] forKey:NSFontAttributeName];
[stringAttributes setObject:[NSColor whiteColor] forKey:NSForegroundColorAttributeName];
[stringAttributes setObject:[NSColor blackColor] forKey:NSBackgroundColorAttributeName];