一、相关网站
### 1.Yogalayout 主页 ### 2.支持的框架 安卓:fblitho主页 github地址 iOS: Componentkit github地址 React Native: React Native github地址
3.参考文章:
参考文章1:【翻译】Yoga 教程: 使用跨平台布局引擎 参考文章2:Yoga 教程: 使用跨平台布局引擎
一、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 项目:如下图
Flexbox 定义 flex item 如何在一个 flex 容器里布局。Flex container之外和 flex item内部的内容会照常渲染。
Flexbox 允许指定Flex item在行与列上的定位和间隔。 对齐内容(justify-content)指定项目沿容器的行与列对齐。
flex-start:定位在容器的开端。 flex-end:定位在容器的末端。 center: 定位在容器的中间。 space-between:项目在容器内被空白空间均匀间隔开,第一个项目在开端位置,最后一个项目在末端位置。 space-around:项目周围以同等空间均匀间隔。 对齐项目(align-items)指定项目沿容器的横轴对齐。下图显示容器的 flex 方向为行时(这意味着横轴垂直运行)的项目展示位置:
项目在容器的开端、中间和末端垂直对齐。 以上初步的 Flexbox 属性应该让你感受了 Flexbox 的工作原理。 还有更多属性可供你使用。 有些控制项目依据可用容器空间来拉伸或收缩的方式。 另一些可以设置填充(padding)、边距(margin),甚至大小(size)。 Flex demo:http://runjs.cn/code/osns3yas
四、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];
}
复制代码
显示效果:
2、运行步骤
第1步:设置view的layout
configureLayoutWithBlock:(YGLayoutConfigurationBlock)block
第2步:将layout应用到view
applyLayoutPreservingOrigin:(BOOL)preserveOrigin
2-1:计算布局
calculateLayoutWithSize
2-2:将布局应用到view层级上
YGApplyLayoutToViewHierarchy