微信iOS多設備多字體適配方案總結


一、背景

2014下半年,微信iOS版先后適配iPad, iPhone6/6plus。隨着這些大屏設備的登場,部分用戶覺得微信的字體太小,但也有很多用戶不喜歡太大的字體。為了滿足不同用戶的需求,我們做了全局字體設置功能,在【設置-通用-字體大小】這里修改設置后,微信大部分界面都會隨之縮放。

 

二、多設備適配

1、各設備的邏輯分辨率:

關於iphone6/6plus的物理分辨率、邏輯分辨率、屏幕物理尺寸、PPI等資料,很多文章已經有詳細說明了,這里就不再累贅。對於終端開發人員來說,其實我們需要關心的,主要是各設備的邏輯分辨率和scaleFactor:

 

需要注意的是,iphone6和6plus可以設置標准模式和放大模式。在放大模式下,6plus會退化為375x667,此時應該當成iphone6來做適配。而iphone6會退化為320x568,應該當作iphone5來適配。

從表中可以看出,適配iphone6/6plus、ipad帶來最大的變化是,屏幕寬度不再是320。以往我們可能一直習慣320寬的屏幕,所以寫界面的時候容易hardcode,例如,如下圖所示,有個按鈕離屏幕左右邊距分別為20,我們可能會把按鈕寬度寫死為280:

UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(20, 15, 280, 46)];

 

但到了iphone6 plus上,屏幕寬度變成414,按鈕的左右邊距就變成20和114,顯得不對稱。在適配時,根據UI需要,此時可能會增加按鈕寬度,改成20+374+20;也可能增加左右邊距,改成67+280+67;也可能兩者都增加,例如改成26+362+26,使得按鈕寬度保持屏幕寬度的7/8。

為了實現這些適配需求,我們的解決方案是,使用配置文件,把界面參數從代碼中分離開來,便於參數的適配。

 

2. 配置文件介紹

配置文件分為兩部分:

第一部分是UI規范配置,把需要統一風格的UI元素定義下來。例如對於鏈接字體顏色,定義LINK_COLOR = rgba(87,107,149,1),所有界面包含鏈接時,鏈接的字體顏色都直接取LINK_COLOR,不單獨harcode,這樣有利於微信的整體UI風格統一、UI規范化,也方便以后UI調整時對鏈接字體顏色做統一修改。

// UI規范化
@colors{
    /* 普通列表(PlainStyle)的背景色 */
    DEFAULT_TABLE_BACKGROUND_COLOR: #2E3132;

    /* 鏈接字體顏色 */
    LINK_COLOR: rgba(87,107,149,1);
}

第二部分是各界面的配置,可以對顏色、字體、切片、數值、坐標、尺寸、frame等進行配置,並根據設備適配的需求定義了一些擴展屬性。

#test_view{
    /* 數值 */
    button_margin1: 20;
    button_margin2: 20 EqualRatio 320;
    button_margin3: 200 EqualDifference 320;
    
    /* frame、尺寸、坐標 */
    logo_frame: 0 0 200 200; /* frame */
    logo_size: 200 200; /* size */
    logo_origin: 0 0; /* origin */

    /* 顏色相關 */
    table_bkg_color: DEFAULT_TABLE_BACKGROUND_COLOR;
    button_bkg_color1: #00C000;
    button_bkg_color2: rbga(255,255,255,0.8);
    button_bkg_color3: clear;

    logo_image: “btn_bkg.png” 40 40; /* 切片 */

    label_font: 16 bold; /* 字體 */
}

下面對其中一些配置加以說明:

button_margin2: 20 EqualRatio 320;

表示在不同設備下做等比縮放,在320寬的屏幕下是20,在iphone6 plus屏幕上就是20 / 320 * 414=26

button_margin3: 20 EqualDifference 320;

表示在不同設備下做等差縮放,在320寬的屏幕下是200,在iphone6 plus屏幕上就是200 + (414-320) = 294

 

table_bkg_color: DEFAULT_TABLE_BACKGROUND_COLOR;

這里使用了UI規范配置里面的定義值

logo_image: “btn_bkg.png” 40 40;

指定了切片的文件,並指定其尺寸(不指定則默認按切片本身的尺寸)。

label_font: 16 bold;

指定字體大小,並為粗體。

 

EqualRatio,EqualDifference這兩個關鍵詞使界面的配置能夠盡量做到一個設計稿適配多種設備。但有時候,我們需要在分設備進行單獨配置,而等差和等比原則又無法滿足。為了解決這個問題,每種設備單獨一個配置文件,目前一共五種設備:默認(iphone5)、iphone4/4s、iphone6、iphone6plus、ipad。讀取配置文件時,先讀默認配置(iphone5),然后根據當前機型再讀取單獨的配置(如果是ipad就讀ipad的配置,如果是iphone5就不用再讀了)。這樣取值時會優先取到單獨的配置,如果沒有單獨配置就取到默認配置。

例如,默認配置中定義:

button_margin1: 20;
button_margin2: 20 EqualRatio 320;
button_margin3: 20;

iphone6plus的配置中定義

button_margin1: 30;

則在iphone6plus中,取到的值分別為button_margin1為30(取6plus配置的值),button_margin2為26(取默認配置的等比原則),button_margin3為20(取默認配置的值)

 

三、界面放大

全局字體設置不是簡單地修改所有字體的大小,以主界面的會話cell為例,如下圖a所示,如果所有字體改大,界面會變成圖b所示,很不協調,兩個label的上下間距也顯得太小,甚至當字體再改大時會出現重疊問題。

為了保證兩個label有足夠的上下邊距,cell的高度需要隨之增加,如圖c所示。這樣會導致左側頭像在cell中顯得太小,於是頭像的寬高也要隨之放大,頭像上的紅點也要跟着放大,……,最終整個界面很多元素(字體、寬高、邊距等)都需要放大。

圖a


圖b

圖c

圖d

至於各元素要放大多少,一開始是想只推出一個大字體版本,由設計師出一套方案。但仔細想想工作量太大了,所有界面都要再出一套設計稿,而且不夠靈活,不同設備上的大字體版都只能按照這套設計稿來。最后我們決定用等比放大的原則,所有元素按照統一一個比例進行放大,這樣出來的效果還不錯,重要的是大大減少了設計和開發的工作量。具體操作是:每個機型設五檔字體,設計師確定各機型上每檔字體的放大比例,開發寫界面時,把字號大小、寬高、邊距等值寫到配置文件里,並指定這些值是否要隨字體設置等比縮放。

在配置文件中,我們增加了關鍵詞dynamic,使得界面能夠支持根據字體設置縮放。例如:

    button_height: 42 dynamic;

表示在不同字體大小設置下,動態縮放。標准字體下高度是42,字體放大50%后高度就是63

    logo_image: “btn_bkg.png” 40 40 dynamic;

指定了切片的文件,並指定其尺寸(不指定則默認按切片本身的尺寸),並且在不同字體大小設置下,動態縮放。

    label_font: 16 bold dynamic;

指定字體大小,並為粗體,同樣根據字體設置動態放大。

 

需要注意的是,在對界面參數等比放大時,放大后的長度值要向上取整。這是因為UIView setFrame傳入的CGRect,如果坐標或寬高值為小數,可能導致文字出現模糊(不銳利)、view出現黑邊等現象。

 

四、webview字體放大

iOS上,可以在webview頁面load完后,設置頁面body的style.webkitTextSizeAdjust屬性,對頁面進行放大。例如:

document.getElementsByTagName("body")[0].style.webkitTextSizeAdjust=“150%”;

這種方法實現簡單,但有兩個問題:

1、對於復雜的圖文頁面,放大后的頁面很難看。例如騰訊新聞頁面的底部,放大后如下圖所示。這是因為字體放大了,但圖片、寬高等其它元素沒有放大。

2、由於要等頁面load完才能重寫webkitTextSizeAdjust屬性,導致頁面load完后還會再刷新一下。

幸好微信里的webview閱讀90%都是公眾號文章,這些頁面樣式相對統一,而且是微信團隊可控的。針對公眾號文章,我們做了以下優化:

1、把用戶的字體設置作為參數傳給公眾號平台,由他們調整頁面樣式后再出頁面,這樣load出來的頁面style就是已經放大的了,不需要客戶端重寫style導致頁面刷新一次。

<html style="-webkit-text-size-adjust: 160%;line-height:1”>

2、如果用戶手動修改webview的字體大小,客戶端會觸發一個jsapi,公眾號頁面監聽並實現這個jsapi,對頁面樣式進行調整。這樣把字體修改的實現方法交給頁面本身,而不是簡單用webkitTextSizeAdjust,可以達到更好的放大效果。

WeixinJSBridge.on(‘menu:setfont’,function(res){ // use fontScale, then set -webkit-text-size-adjust and line-height
});

 

對於非公眾號文章,目前默認不隨全局字體設置做放大,如果用戶手動修改webview的字體大小,會用webkitTextSizeAdjust修改。后續可以把這個jsapi推廣到騰訊新聞插件,甚至開放出去,盡量把字體修改的實現方式交給頁面。

 

 

五、iOS9 iPad分屏多任務

WWDC2015上推出了iPad分屏多任務功能,使得iOS設備的邏輯分辨率又多了五種:


分屏類型 分辨率
豎屏-小屏 320*1024
豎屏-大屏 438*1024
橫屏-小屏 320*768
橫屏-半屏 507*768
橫屏-大屏 694*768

使用目前的適配方案,能夠很快地適配iPad分屏。具體方法是:
1、對於320*768和320*1024的屏幕大小,用iphone5的配置參數;
2、對於其它屏幕大小,使用ipad的配置參數,並對必要的參數根據屏幕大小指定等差/等比縮放。

 

六、總結

界面參數寫在配置文件有幾個好處:

1、能夠很快適配不同機型:對必要的參數指定等差縮放或等比縮放,就可以做到一個設計稿適配多種設備。

2、方便對不同機型做特殊處理:有時候個別參數在不同設備上有差異,而等差/等比原則又無法滿足需求。如果參數寫在代碼里面,就有一堆機型的if判斷:

if (isIpad) …;
else if (isIphone6) …;
else …

而寫在配置文件里,只需要根據不同機型讀相應配置文件即可。

3、能夠很快適配不同字體大小:配置文件里指定哪些參數需要等比縮放,哪些是固定值,讀參數的時候做一下處理,就可以實現界面縮放,不需要修改代碼。

4、方便界面參數調整:設計師做界面微調時,可以自己修改配置文件,快速確認效果,不需要先跟開發溝通,等開發修改完代碼后再確認。一方面減少了溝通成本,另一方面也減輕了開發的負擔。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM