小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

關(guān)于字體適配的那些事

 最初九月雪 2016-04-13

前言

之前做過(guò)很多項(xiàng)目都沒(méi)考慮過(guò)字體適配問(wèn)題。相信絕大多數(shù)人在做項(xiàng)目時(shí),都沒(méi)仔細(xì)去考慮這件事。一般都是根據(jù)UI出的圖做個(gè)估算,有耐心的估計(jì)會(huì)自己拿工具測(cè)量下。如今,考慮到iPhone機(jī)型的多樣性,UI設(shè)計(jì)師不可能針對(duì)每一款iPhone的屏幕出一套UI圖。一般而言,都是基于5s的標(biāo)準(zhǔn)出UI。當(dāng)我們?cè)谠O(shè)置字體時(shí),往往都是基于UI并且針對(duì)不同的屏幕字體也都是絕對(duì)的。那么問(wèn)題來(lái)了,細(xì)心的同學(xué)可能會(huì)注意到,相同大小的字體在5s或6上也許差別不大,但在6p上字體有縮小的現(xiàn)象,其原因由分辨率導(dǎo)致。
在6出來(lái)不久,曾看過(guò)有關(guān)適配的文章,其中關(guān)于iPhone尺寸規(guī)格如下:

設(shè)備 對(duì)角線(xiàn) 邏輯分辨率 scale Factor 設(shè)備分辨率 PPI
3GS 2.4inch 4.5inch 3.5inch 320x480 @1x 320x480 163
4(s) 2.31inch 4.5inch 3.5inch 320x480 @2x 640x960 326
5c 2.33inch 4.90inch 4inch 320x568 @2x 640x1136 326
5(s) 2.31inch 4.87inch 4inch 320x568 @2x 640x1136 326
6 2.64inch 5.44inch 4.7inch 375x667 @2x 750x1334 326
6p 3.06inch 6.22inch 5.5inch 414x736 @3x 1242x2208 401

從iPhone3GS/iPhone4(s)過(guò)渡到iPhone5(s)時(shí),在邏輯上寬度不變高度稍高,之前舊的素材和布局通過(guò)AutoresizingFlexible簡(jiǎn)單適配即可運(yùn)行得很好,但由于高寬比增大,上下兩端出現(xiàn)黑粗邊(典型如LaunchImage)。從分辨率的角度來(lái)看,除了需要提供LaunchImage這種滿(mǎn)屏圖,其他基本沿用二倍圖(@2x);從屏幕尺寸角度來(lái)看,需要對(duì)縱向排版略加調(diào)整。
從iPhone5(s)發(fā)展到iPhone6(+),由于高寬比保持不變,iOS對(duì)圖標(biāo)、圖片、字體進(jìn)行等比放大自適應(yīng),清晰度會(huì)有所降低。同時(shí),絕對(duì)坐標(biāo)布局會(huì)導(dǎo)致在大屏下出現(xiàn)偏左偏上的問(wèn)題。從分辨率的角度來(lái)看,iPhone6沿用二倍圖(@2x),但需為iPhone6+提供更高的三倍圖(@3x);從屏幕尺寸角度來(lái)看,需要重新對(duì)UI元素尺寸和布局進(jìn)行適配,以期視覺(jué)協(xié)調(diào)。

字體適配

以上屬于科普類(lèi)的東西,下面來(lái)點(diǎn)實(shí)際的。

關(guān)于字體適配有2種方案。

  • 方案一:
    設(shè)置一個(gè)大小區(qū)域范圍,比如10~30pointSize的范圍(pointSize為UIFont的一個(gè)CGFloat類(lèi)型的屬性),然后for循環(huán)降序遍歷此范圍設(shè)置一個(gè)臨時(shí)的UIFont變量,根據(jù)此變量計(jì)算當(dāng)前文本的大小,與當(dāng)前UILabelheight作比較找出合適的字體。
#define ADAPTIVE__FONT_SIZE_MINIMUM_VALUE 20
#define ADAPTIVE_FONT_SIZE_MAXIMUM_VALUE 30

-(UIFont *) adjustFontSizeToFillItsContents
{
    NSString* text = self.text;

    for (int i = ADAPTIVE_FONT_SIZE_MAXIMUM_VALUE; i>ADAPTIVE__FONT_SIZE_MINIMUM_VALUE; i--) {

        UIFont *font = [UIFont fontWithName:self.font.fontName size:(CGFloat)i];
        NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text attributes:@{NSFontAttributeName: font}];

        CGRect rectSize = [attributedText boundingRectWithSize:CGSizeMake(self.frame.size.width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin context:nil];

        if (rectSize.size.height <= self.frame.size.height) {
            return [UIFont fontWithName:self.font.fontName size:(CGFloat)i];
            break;
        }
    }
    return self.font;
}
  • 方案二:
    計(jì)算出一個(gè)scale重新設(shè)置UIFont,偽代碼如下:
CGFloat scale = ([UIScreen mainScreen].bounds.size.width / 320);
NSLog(@"before : %.1f", [font pointSize]);
font = [UIFont fontWithName:[font fontName] size:fontSize * scale];
NSLog(@"after : %.1f", [font pointSize]);

既然需要重新設(shè)置UIFont,那么我們不可避免的要hookUIFont的類(lèi)方法`fontWithName:size:做個(gè)函數(shù)交換的處理。
函數(shù)的交換我們需要用到runtime機(jī)制。

void bd_exchageClassMethod(Class aClass, SEL oldSEL, SEL newSEL)
{
    Method oldClsMethod = class_getClassMethod(aClass, oldSEL);
    assert(oldClsMethod);
    Method newClsMethod = class_getClassMethod(aClass, newSEL);
    assert(newClsMethod);
    method_exchangeImplementations(oldClsMethod, newClsMethod);
}

然后,我們給UIFont創(chuàng)建一個(gè)Categroy文件,文件名為AdaptiveFont。在實(shí)現(xiàn)文件代碼如下:

@implementation UIFont (AdaptiveFont)

+ (void)hook
{
    bd_exchageClassMethod([UIFont class], @selector(fontWithName:size:), @selector(hook_fontWithName:size:));
}

+ (UIFont *)hook_fontWithName:(NSString *)fontName size:(CGFloat)fontSize
{
    NSLog(@"before : %.1f", fontSize);
    CGFloat scale = ([UIScreen mainScreen].bounds.size.width / 320);
    NSLog(@"scale : %f", scale);
    UIFont *font = [self hook_fontWithName:fontName size:fontSize * scale];
    NSLog(@"after : %.1f", [font pointSize]);
    printf("<--------------------->\n");
    return font;
}

@end

接口文件暴漏相關(guān)方法如下:

@interface UIFont (AdaptiveFont)

+ (void)hook;
+ (UIFont *)hook_fontWithName:(NSString *)fontName size:(CGFloat)fontSize;

@end

相對(duì)比較而言,我還是傾向于方法二。方法一的前提條件是height要適配好,不能是絕對(duì)值,否效果。當(dāng)然,方法二也一樣,只不過(guò)height若是絕對(duì)值,會(huì)出現(xiàn)文字顯示不全的問(wèn)題。
在用法上,方法一只需調(diào)用adjustFontSizeToFillItsContents,而方法二需在application:didFinishLaunchingWithOptions:函數(shù)調(diào)用下hook。

當(dāng)然,這并不是最終也不是最好的適配方案。個(gè)人覺(jué)得根據(jù)PPI適配字體,限于經(jīng)歷有限只能研究到這。
歡迎糾錯(cuò),有什么好的字體適配方案也可以在下方評(píng)論進(jìn)行探討。

Demo地址:https://github.com/keleyundou/AdaptiveFontDemo

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多