前言
這篇文章主要是對Weex iOS端原始碼中的佈局原理進行分析,並根據原理寫了一個Demo,歡迎大家進行交流溝通。
Layout 介紹
Layout是FaceBook開源的一個跨端CSS佈局引擎。 Weex 引入了Layout 在原來的基礎上進行名稱空間上的調整, Layout在Weex中主要是作為一個CSS引數的容器,對CSS的引數的管理。
Layout原始碼
Layout原始碼由C語言編寫,主要包含可以儲存CSS引數的結構體、列舉,以及一些相關的C函式。 1、結構體、列舉 Layout.h檔案中宣告瞭對應於CSS屬性的一些結構體和列舉體 如:
css_style_t
css_layout_t
css_node_t
css_direction_t
css_flex_direction_t
css_justify_t
css_align_t
css_position_type_t
css_wrap_type_t
css_position_t
···
複製程式碼
對CSS有了解的夥伴可以看出,這些結構體的命名上和CSS的屬性是相對應的
其中比較核心的一個資料結構體是css_node_t
,裡面包含了CSS佈局需要的大部分引數:
2、C函式
layout中實現了一些管理css_node_t
等結構體的生命週期的C函式:
css_node_t *new_css_node(void);
void init_css_node(css_node_t *node);
void free_css_node(css_node_t *node);
void layoutNode(css_node_t *node, float maxWidth, float maxHeight, css_direction_t parentDirection);
void resetNodeLayout(css_node_t *node);
複製程式碼
這些函式包括了初始化、析構、重置等功能。
Weex佈局原理
大概流程:
一、通過JS載入資料
Weex通過JSContext讓APP與JS進行互動,相關載入的資料通過JSValue進行載入。 JSValue資料結構大致如下:
{
attr = {
data-v-e9c9dede = ;
};
style = {
bottom = 48wx;
position = absolute;
width = 0;
left = 0;
top = 0;
opacity = 0;
backgroundColor = rgba(0,0,0,0.5);
};
type = div;
event = (
click
);
ref = 558;
}
複製程式碼
通過JS獲取JSValue:
二、轉換成iOS原生可用的佈局資料 存進css_node_t
在獲取JSValue之後通過toDictionary
方法轉化成原生直接可用的NSDictionary格式的資料。
再將NSDictionary資料轉換到css_node_t中
Weex中封裝了一些巨集用於轉換,如:
WX_STYLE_FILL_CSS_NODE
WX_STYLE_FILL_CSS_NODE_PIXEL
WX_STYLE_FILL_CSS_NODE_ALL_DIRECTION
複製程式碼
這些巨集主要是獲取NSDictionary中各個key的value(即CSS屬性的資料)計算成原生布局可用的資料,存入css_node_t
中對應的成員裡。
Weex提供了一些方法將CSS屬性的資料計算轉換成佈局可用的資料:
例如數值轉換:
+ (CGFloat)CGFloat:(id)value
方法就是將其轉換成原生布局可以用的數值。
三、進行佈局
需要佈局時,從css_node_t
取出資料,對View進行佈局。
如:
css_node_t
中取出資料,計算出frame(即View的位置和大小),進行佈局
其他細節
佈局數值的精確度
在layout中實現了一個比較函式eq
:
static bool eq(float a, float b) {
if (isUndefined(a)) {
return isUndefined(b);
}
return fabs(a - b) < 0.0001;
}
複製程式碼
從中可以看出,所以在weex中佈局相關數值的精確度偏差最低為0.0001,如0.00011和0.00019在weex佈局中視為一樣。
標籤採用繪製成圖片的形式展示
從原始碼可以看出,