跨平臺布局引擎Yoga的學習和使用

一、相關網站

1.Yogalayout

主頁

2.支持的框架

安卓:fblitho主頁 github地址
iOS: Componentkit github地址
React Native: React Native github地址

3.參考文章:

參考文章1:【翻譯】Yoga 教程: 使用跨平臺布局引擎
參考文章2:Yoga 教程: 使用跨平臺布局引擎

yoga1.png

一、Yoga的發展

Yoga是一個基于Flexbox的跨平臺布局引擎,能使布局工作更輕松。
Yoga 作為一個通用的布局系統,來代替iOS上的AutoLayout 或 web 上的 Cascading Style Sheets (CSS)。
最初是Facebook在2014年推出的一個CSS布局的開源庫,2016年改版并更名為Yoga。Yoga 支持多個平臺,包括 Java、C#、C 和 Swift。
庫開發者可以集成Yoga到布局系統,就如 Facebook 已經集成進React Native/Litho/Componentkit。Yoga 也是一個 iOS 開發者可以直接用來布局視圖的框架。

二、了解Flexbox

Flexbox 也稱為 CSS Flexible Box,被創建用來處理 web 上的復雜布局。
一個關鍵特征是在給定方向上高效布局內容,并能“靈活”處理自身大小來適應一些空間。
Flexbox 由 flex 容器組成,每個含有一個或多個 flex 項目:如下圖


flexbox1.png

Flexbox 定義 flex item 如何在一個 flex 容器里布局。Flex container之外和 flex item內部的內容會照常渲染。

flexbox2.png

Flexbox 允許指定Flex item在行與列上的定位和間隔。
對齊內容(justify-content)指定項目沿容器的行與列對齊。

flexbox3.png

flex-start:定位在容器的開端。
flex-end:定位在容器的末端。
center: 定位在容器的中間。
space-between:項目在容器內被空白空間均勻間隔開,第一個項目在開端位置,最后一個項目在末端位置。
space-around:項目周圍以同等空間均勻間隔。
對齊項目(align-items)指定項目沿容器的橫軸對齊。下圖顯示容器的 flex 方向為行時(這意味著橫軸垂直運行)的項目展示位置:

flexbox4.png

項目在容器的開端、中間和末端垂直對齊。
以上初步的 Flexbox 屬性應該讓你感受了 Flexbox 的工作原理。
還有更多屬性可供你使用。
有些控制項目依據可用容器空間來拉伸或收縮的方式。
另一些可以設置填充(padding)、邊距(margin),甚至大小(size)。
Flex demo:http://runjs.cn/code/osns3yas

flexbox5.png

四、Yoga 對比Flexbox

Yoga 是基于 Flexbox 的,也有一些不同。
Yoga 并沒有實現全部 CSS Flexbox。
它省略了非布局屬性,如設置顏色。
Yoga 改進了一些 Flexbox 的屬性來提供更好的從右到左的支持。
最后,Yoga 增加了一個新的比例(AspectRatio)屬性來處理在布置某些元素如圖片時常見的需求

五、使用YogaKit(OC/Swift)來構建布局

Yoga API 將使你沐浴在 Flexbox 熟悉度的余暉中。可以在 Swift app 布局中應用你學到的 Flexbox。
Yoga 使用 C 編寫,主要關注于優化性能和簡便集成到其它平臺。
對于開發 iOS app,你將使用 YogaKit 工作,這是一個由 C 實現的封裝包。
回顧 Flexbox 在 web 里的樣例,布局是通過樣式屬性來配置的。
而 YogaKit,布局配置是交由 YGLayout 對象來完成。
YGLayout 包含的屬性有 flex 方向,對齊內容,對齊項目,填充和邊距。
YogaKit 曝露 YGLayout 作為 UIView 上的一個 Category。
這個 Category 添加 configureLayout(block:) 方法到 UIView。
將 YGLayout 參數傳進block里,并使用這些信息來配置視圖的布局屬性。
通過使用所需的 Yoga 屬性配置每個參與的視圖來構建你的布局。
一旦完成,你在根視圖的 YGLayout 上調用 applyLayout(preservingOrigin:)。
這會計算并應用布局到根視圖和子視圖。

1、布局代碼

完整代碼

Podfile文件內容

platform :ios, '10.0'
use_frameworks!
target "YogaKitDemo" do
pod 'Yoga', '~> 1.6.0' //yoga 使用c/c++實現
pod 'YogaKit' //提供給Objective-C和Swift使用
end
-(void)dodoViews
{
    
    [self.view configureLayoutWithBlock:^(YGLayout * layout) {
        layout.isEnabled = YES;
        layout.width = YGPointValue(self.view.bounds.size.width);
        layout.height = YGPointValue(self.view.bounds.size.height);
        layout.alignItems = YGAlignCenter;
    }];
    
    UIView *contentView = [[UIView alloc]init];
    contentView.backgroundColor = [UIColor lightGrayColor];
    [contentView configureLayoutWithBlock:^(YGLayout * layout) {
        layout.isEnabled = true;
        // 4
        layout.flexDirection =  YGFlexDirectionRow;
        layout.width = YGPointValue(320);
        layout.height = YGPointValue(80);
        layout.marginTop = YGPointValue(100);
        
        layout.padding =  YGPointValue(10);//設置了全部子項目的填充值
    }];
    
    UIView *child1 = [[UIView alloc]init];
    child1.backgroundColor = [UIColor redColor];
    [child1 configureLayoutWithBlock:^(YGLayout * layout) {
        layout.isEnabled = YES;
        layout.width = YGPointValue(80);
        layout.marginRight = YGPointValue(10);
    }];
    
    
    
    UIView *child2 = [[UIView alloc]init];
    child2.backgroundColor = [UIColor blueColor];
    [child2 configureLayoutWithBlock:^(YGLayout * layout) {
        layout.isEnabled = YES;
        layout.width = YGPointValue(80);
        layout.flexGrow = 1;
        layout.height = YGPointValue(20);
        layout.alignSelf = YGAlignCenter;
        
    }];
    
    [contentView addSubview:child1];
    [contentView addSubview:child2];
    [self.view addSubview:contentView];
    [self.view.yoga applyLayoutPreservingOrigin:YES];

}

顯示效果:


yoga1.png

2、運行步驟

第1步:設置view的layout

configureLayoutWithBlock:(YGLayoutConfigurationBlock)block

第2步:將layout應用到view

applyLayoutPreservingOrigin:(BOOL)preserveOrigin

2-1:計算布局

calculateLayoutWithSize

2-2:將布局應用到view層級上

YGApplyLayoutToViewHierarchy

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容