• Posts tagged "iOS"

Blog Archives

iOS使用自定义字体

iOS 6 自带字体:iOS 6: Font list

iOS 7 自带字体:iOS 7: Font list

OS X Mavericks 自带字体:
OS X: Fonts included with Mavericks

上面两篇文档里列出的字体名字并非编程时用的fontName,只是对应的字体文件的名字。

可以使用下面的代码查系统自带字体的 fontName,在任意 UIViewController 里加上:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    for (NSString* family in [UIFont familyNames])
    {
        NSLog(@"%@", family);
        for (NSString* name in [UIFont fontNamesForFamilyName: family])
        {
            NSLog(@"%@", name);
        }
    }
}

以下是真机 debug 在控制台打印出来的:

Thonburi
Thonburi-Bold
Thonburi
Thonburi-Light
...
Didot-Bold
Didot-Italic
Didot
DIN Alternate
DINAlternate-Bold
Bodoni 72 Smallcaps
BodoniSvtyTwoSCITCTT-Book

加入我想要在 iOS 的 UILabel 中使用 mac 中自带的Yuanti SC,怎么搞?
1.下载你想要的字体的字体文件,可以是 ttf、otf、ttc 等格式(ttc 格式需要特别注意),此处我从 mac 的系统默认字体存储目录拷贝;
2.把字体文件添加到 xcode 项目中;
2.在Info.plist添加以下代码并保存;

    
   UIAppFonts
	
		Yuanti.ttc
		WawaSC-Regular.otf
		Lantinghei.ttc
		汉仪楷体简.ttf
	
   

B261A1C3-2E8F-4006-8AFE-B4831828E225
3.在 Build Phases/Copy Bundle Resources添加字体文件;
70428009-10BC-4667-B5B7-D985179CC12F
4.使用上面 viewDidLoad 代码查找新增的 fontName,比如我添加 Yuanti.ttc 后新增了

Yuanti SC
STYuanti-SC-Light
STYuanti-SC-Bold
STYuanti-SC-Regular

最后在代码中

self.contentLabel.font = [UIFont fontWithName:@"Yuanti SC" size:16.0f];

效果:
83E5E5D7-4417-4015-BAB0-80EE6964554B

Lantinghei.tcc 下面包含8个字体。

Lantinghei TC //繁体细
FZLTXHB--B51-0 //繁体extralight
FZLTTHB--B51-0 //繁体heavy
FZLTZHB--B51-0 //繁体demibold
Lantinghei SC //简体
FZLTZHK--GBK1-0 //简体demibold
FZLTTHK--GBK1-0 //简体heavy
FZLTXHK--GBK1-0 //简体extralight

如果不适用粗体,就直接用Lantinghei SC就可以了。

ttc 字体文件是字体集合,提取 ttc 字体名方法:

-(NSArray*)customFontArrayWithPath:(NSString*)path size:(CGFloat)size
{
    CFStringRef fontPath = CFStringCreateWithCString(NULL, [path UTF8String], kCFStringEncodingUTF8);
    CFURLRef fontUrl = CFURLCreateWithFileSystemPath(NULL, fontPath, kCFURLPOSIXPathStyle, 0);
    CFArrayRef fontArray =CTFontManagerCreateFontDescriptorsFromURL(fontUrl);
    CTFontManagerRegisterFontsForURL(fontUrl, kCTFontManagerScopeNone, NULL);
    NSMutableArray *customFontArray = [NSMutableArray array];
    for (CFIndex i = 0 ; i < CFArrayGetCount(fontArray); i++){
        CTFontDescriptorRef  descriptor = CFArrayGetValueAtIndex(fontArray, i);
        CTFontRef fontRef = CTFontCreateWithFontDescriptor(descriptor, size, NULL);
        NSString *fontName = CFBridgingRelease(CTFontCopyName(fontRef, kCTFontPostScriptNameKey));
        UIFont *font = [UIFont fontWithName:fontName size:size];
        [customFontArray addObject:font];
    }
    
    return customFontArray;
}

另一种思路是直接从 ttc 提取 ttf,有待研究。

参考资料:

Tutorial: Porting fonts to the iPhone

iPhone 6和6Plus屏幕、UI设计和适配那些事

且看iPhone几个系列的屏幕数据:

 iPhone 4*iPhone 5*iPhone 6iPhone 6P
物理大小 - 对角(inch)3.544.75.5
物理大小 - 宽高(inch)1.94*2.911.96*3.482.3*4.12.7*4.79
PPI329.65325.97325.61400.53
物理分辨率(px)640*960640*1136750*13341080*1920
逻辑分辨率(pt)320*480320*568375*667414*736
渲染分辨率(px)640*960640*1136750*13341242*2208
像素/点比率2222.6

首先要看到的事实是6P的ppi变大了,也就是像素更小了。如果还是按1:2的点像比,那么这块1080*1920像素分辨率的屏幕应该有540*960的点分辨率。但实际计算用到点分辨率却是414*736,点像比是1:2.6,不到1:3。
那么问题来了,为什么苹果不沿用326ppi左右屏幕,而要用401ppi的屏幕?为什么6P的点分辨率是414*736?

关于这些问题可以参考知乎iPhone 6 Plus的逻辑分辨率为什么是414×736?
大概就是保证:
1.6P屏幕必须6大,5.5英寸为前提;
2.显示更多内容,所以点分辨率必须大于375*667;
3.ppi不能比之前低;
4.同样逻辑单位(点)的内容,如字体、按钮物理尺寸不能比之前小,否者会造成视觉、操作不便。
5.在现有工艺可达到。
所以最终401ppi、414*736、1080*1920、1:2.6的配置更像是一种折中的非完美方案。

问题又来了,为什么不是326ppi、880*1560(880≈2.7”*326ppi,1560≈4.79”*326ppi)、440*780、1:2这种尺寸呢?

这样还可以继续用2x图。这里就略过不研究了。

如有2.6对于开发、设计来说都不是一个特好的数字,所以苹果把它约等了一下变成3,又搞了个渲染分辨率的概念。
414*736的3倍正是1242*2208,在这个分辨率计算界面的样式,然后把最终的画面下采样(downsampling)缩小1.15显示到1080*1920上。渲染分辨率还用在未专门适配4.7英寸的iPhone 6的时,把4英寸的640*1136画面上采样(upsampling)放大1.171875倍显示在750*1334屏幕上,当然会看起来比较模糊。采用3的话以后如果采用461ppi屏幕也更容易兼容。

iPhone 6 plus downsampingiphone 6 upsampling

更全更详细的图示请参见:The Ultimate Guide To iPhone Resolutions

PPI计算和常见手机PPI信息:https://www.sven.de/dpi/

以主屏幕分辨率的app图标为例,大小为60pt*60pt,为什么@3x下icon的尺寸180*180就是正确的呢?在@2x下120*120的icon,物理尺寸是0.36”≈120px*1.96”/640px,而@3x下180*180的icon物理尺寸是0.39≈(180px/11.5)*2.7”/1080px。可见他们的物理尺寸基本一致。

对于6P,@2x素材的大小乘以1.5便是@3x图的大小。

对于iPhone 5系,屏幕只是变长了,垂直方向上的适配很简单。然后对于6和6p来说,不仅边长变宽,点像比率也变大了。那么在设计iPhone UI时就不再像以前一样了。应该结合使用point、autolayout的“相对”布局,什么时候该用固定point大小,什么时候该用相对尺寸,具体并没有可套用的准则。

比如主屏icon图标保证尺寸是60point,横向平分间隔;相册里每行4张缩略图,4等分,没有具体point大小;nav bar是同一Point大小;tab bar图标统一point大小,间隔均分。

在出设计图给程序员时的标注也不再全部是绝对的像素或pt,像间隔应该表明是横向均分。

用markman标注

在设计时应该以哪个iPhone为参考呢?画布尺寸为多大呢?
画布应该以iPhone4的点分辨率320px*480px,放大3倍,即960px*1440px为标准。这样既保证了UI对最小屏幕的绝对适配,也方便了@3x素材的导出。
在横向上,6和6P使空白区域拉伸即可。纵向可以结合留白、放大、使用滚动。

 

在编程实现应该使用Autolayout,摒弃过去的绝对pt布局。

使用代码进行布局时可以使用一些对原生NSLayoutConstraints的封装简化库,减少臃肿,提高代码可读性,加快速度。

MasonryPureLayoutKeepLayout

本人使用 PureLayout,虽然语法没 Masonry 那么简单,但是 bug 少。