UIFont and Retina displays. Double the size? - ios

I think I might already know the answer, but here is the situation:
I have a spec sheet that requires the font size to be: 11pt.
When I do: UIFont *font = [UIFont fontWithName:#"Gotham" size:11.0];
Then font is tiny on my retina iPad 4.
When I double the point count with: UIFont *font = [UIFont fontWithName:#"Gotham" size:22.0];
The size looks right. Am I right to assume that I should double the font point count for #2x devices? Just as one would for a png.
Edit:
Thanks for clearing that up. I get that: UIFont *font = [UIFont fontWithName:#"Gotham" size:11.0]; Will produce the same size on Retina/Non-retina.
Now for possibly more dumb follow up:
When I open up the photoshop file (scaled at #2x) the font reads 11pt. When I export the file (converted to png and labeled #2x) and I drop the png into the project, why does the image's text still appear significantly bigger than the text I created programmatically at 11pt? (Both the image and programatic text are being viewed within the iPad)
I'm probably having a brain fart, but any help finding the solution would be appreciated.

No, you don't need to scale font sizes. Font sizes are in points, not pixels. The reason why 11.0 seems tiny to you is because it really is ;-)
But the size should be the same regardless wether it's a retina device or not.

If you are doing this right, you should be able to ignore pixels and think entirely in terms of points, the native measurement unit:
If you have a built-in interface widget, such as a UILabel, then [UIFont fontWithName:#"Gotham" size:11.0] will look the same size on Retina and non-Retina devices (but sharper on Retina).
If you are constructing an image in real time (in code), and you are using this font to draw into the image, then if this is to be a 2x image for double-resolution screen, then you should be using a double-resolution graphics context (e.g. you set this up with UIGraphicsBeginImageContext(size,NO,0)) and once again [UIFont fontWithName:#"Gotham" size:11.0] will look the same size on Retina and non-Retina devices (but sharper on Retina).
On the other hand, let's say you are preparing an image in Photoshop, to be used later in your iOS app (e.g. for an icon), and this image has some font drawing within it. Then of course for a 2x version of the image you must double the font size, just as you are doubling the size of everything in the drawing.

Related

Actual display size of IOS fonts doesn't match metrics

I am writing an iPad app which requires letters to be displayed at their exact point size regardless of screen size.
I've implemented the text display using a UILabel object. I have the Autoshrink property set to Fixed Font Size, however the letters on the screen are much smaller than indicated by the font metrics. For instance the capitals of a 251 point font, which should be 3.5 inches tall, are only 2 inches on the screen. At different point sizes the same shrinkage happens.
The fontCapHeight is the same as the font size with the font I am using.
How can I make the displayed size is the same as the font size?
For instance the capitals of a 251 point font, which should be 3.5 inches tall, are only 2 inches on the screen.
You're assuming a point is 1/72", which is not true. That's a desktop publishing point. A point in iOS is a certain number of pixels (based on the scale). The number of pixels in an inch are a factor of the screen's pixel density (PPI). iOS provides no way to query for that that I'm aware of. You have to just have a big table that knows. A fairly nice one for that is GBDeviceInfo, but ultimately it just has a big table of values based on looking up specs or measuring screens.
You need your cap height (pt) to be (ppi/scale)*inches, but you can't set cap height directly. You need to set it via the em box size (the "font size"). Here's an example. It takes a label containing a font of any size and make it's cap height be 3".
let font = label.font!
let ppi = 326.0 // iPhone 6s
let scale = Double(UIScreen.main.scale)
let desiredSize = 3.0 // inches
let emBoxRatio = Double(font.pointSize / font.capHeight)
let fontSize = (ppi / scale) * desiredSize * emBoxRatio
label.font = label.font.withSize(CGFloat(fontSize))
Keep in mind that "make its cap height be 3 inches" is not the same thing as "make any particular letter be 3 inches." It depends on the font and the letter. In many fonts, glyphs with a curved top are a little taller than the cap height, and some ascenders may be a little taller than the cap height. While H, X, and I are often exactly the cap height, sometimes they're a little shorter (sometimes O is the cap height rather than X). Sometimes glyphs are above their baseline. There is nothing that says that a font even has to fit within its em box, and some fonts draw wildly outside (Zapfino, I'm looking at you).
My only point here is that you need to check your actual font carefully. Font metrics are serving suggestions at best. They're meant to make fonts with similar metrics "feel" the same. They're not always absolute measures of things.
I don't understand this:
The fontCapHeight is the same as the font size with the font I am using
If the cap height is the same as the "font size" (em box height), then where are the descenders? It feels like you've run out of em box.
Problem solved. I found the following statement at http://blog.fluidui.com/designing-for-mobile-101-pixels-points-and-resolutions/ : "An iOS point is equivalent to 1/163 of an inch. This size is always the same regardless of the resolution of the phone it is on, and comes from the 163DPI of the original iPhone." I couldn't find it anywhere in the Apple documentation, but I'm sure it is there somewhere!

changing the font size according to each iPhone size

is there any way to changing/auto resizing the font size according to the different iPhone screen as when i change the font size, the font size applied to other phone size as well which is too big.
My Current Phone size is iPhone 6s plus (5.5 inch)
Please use size classes to support different font size for different screens. Here is good tutorial about using size classes. adaptive-layout-tutorial
I ran in to a similar issue. I suggest to use this library:
https://github.com/hamiz-ahmed/SizeOptimizedLabel
Specify the initial screen and font size. The font gets optimized automatically according to different screen sizes.
I faced this issue few months ago. There is no way to do it on storyboard for now.
You can do it by code by detect screen size or device type and set font size for each device. You can use this lib to do that
https://github.com/sebyddd/SDVersion

Poor font quality in CCLabelBMFont

Scaled screenshot on iPhone 5S:
CCLabelBMFont is on top and CCLabelTTF is at the bottom.
Both strings use Helvetica Neue Light 17pt.
As you can see there is some kind of a stroke in the first string, but all symbols in font image are white on transparent background. Is it possible to get rid of this effect and make CCLabelBMFont look just as good as CCLabelTTF?
I used bmGlyph and other free analogs for Bitmap font creation, results were always the same.
First, don't change the node's scale property or it will be blurry.
You need to make a HD version of the font, where the font's png filename has the -hd suffix and the font size is double that for non-Retina devices. For example:
Non-Retina font with 32pt size (if you support non-retina devices):
font.fnt
font.png
Then create a font with 64pt size and save it as:
font-hd.fnt
font-hd.png
What a relief!
Turned out it's because of Blend src property.
I changed this property on my label from default in SpriteBuilder 'One' to 'Dst Alpha' and now it's impossible to see any difference between CCLabelTTF and CCLabelBMFont!

UIFont: Font size differs

I am setting a custom font to all subviews (such as UILabels) inside my view by a custom function. However, if I try to correct the font size for specific UILabels only via
[lbl_EXAM_Statistics setFont:[UIFont fontWithName:#"PTSans-Regular" size:13]];
The 13point seems to be a little "too small" from what was given me from the Screendesign.
In the psd file however its 13pt to be exact.
Why does the 13pt font size differ from the 13pt font size in my app?
In the screenshot the above text is from the psd file, the bottom one from the iphone simulator.
If I want to get near the text size from the Screendesign to my app I'd have to use somewhat of 18pt - but I cant waste time playing around how to get the exact pt, thats a huge timewaste with all the font size I have to specify directly. So there must be a better way.
Totally depends on your psd.
Best is to set your metrics in Photoshop in pixels. So you can see the size of your font in pixels.
Then if your PSD is at retina size (640 px width), you just have to devide by 2 the px size of your font and you will have the good result on your app.
In the end, don't use pt but px in your PSD and it will be allright (just have to think that 1point in iOS is 2px on retina screen and 1px on non-retina)
Photoshop's font size and the iPhone's should match assuming the PSD file is set to 72dpi (or 144 for retina images).
You can check this in Photoshop using Image->Image Size... and then set the resolution to 72 pixels/inch (keeping the pixels untouched by unchecking "Resample Image:"). If the image is for retina resolution, use 144 pixels/inch.
This will not change the image in any way but make all pt measurements in Photoshop match the iPhone's coordinate system, retina or not.

UIColor pattern with UIImage for retina display

I hope this is a quick fix.
I'm trying to repeat a UIImage as a background texture and of course I want to accomodate for Retina display.
I have a background image (22px wide and 640px tall) that I want to repeat on the x-axis (it is oriented to Landscape) but have it scaled down to 11pt wide and 320pt tall. I tried:
UIColor *c = [UIColor patternWithImage:[UIImage imageNamed:#"bg#2x.png"]];
[scrollView setBackgroundColor:c];
and it does not scale down, though it does repeat.
Any suggestions to how I can scale it down?
I guess I'll write this as an answer, but the main problem (for the scaling at least) is that the system does not know that it IS in fact a retina image. It needs to search for the filename without the #2x, and then if there is an #2x, it will know it is supposed to be a retina version and thus will be scaled down.
ie. just do
[UIColor patternWithImage:[UIImage imageNamed:#"bg"]];

Resources