Yoga是一个基于Flexbox布局思想的跨平台的布局库。也就是说,Yoga布局库是对Flexbox布局思想的一种实现。
Yoga最初是FaceBook在2014年推出的一个CSS布局的开源库,2016年改版并更名为Yoga。
Yoga是一个跨平台库,支持Java、C#、C、Swift等多个平台。
库的开发者可以集成Yoga进布局系统,例如FB已经将Yoga集成进ReactNative、Litho、ComponentKit,阿里的Weex也是使用Yoga来实现Flexbox布局的。
YogaKit是对Yoga在iOS开发平台上的封装,我们可以直接使用YogaKit来进行页面视图的布局。
YogaKit的布局配置是交由YGLayout对象来完成,YGLayout包含的属性有flex方向、对齐内容、对齐项目、t填充和边距。YogaKit暴露YGLayout作为UIView上的一个Category,这个Categoryt添加configureLayoutWithBlock:方法到UIView,将YGLayout参数传进block里,并使用这些信息来配置视图的布局属性。通过所需的Yoga属性配置每个参与的视图来构建你的布局。一旦完成,你在根视图的YGLayout上调用applyLayoutPreservingOrigin:方法,这会计算并应用布局到根视图和子视图。
使用cocoapods进行安装:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, "8.0"
use_frameworks!
target 'AppDemo' do
pod 'YogaKit', '~> 1.5'
end
代码中导入
#import <YogaKit/UIView+Yoga.h>
先布局一个试试手:
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.backgroundColor = [UIColor redColor];
[view configureLayoutWithBlock:^(YGLayout * layout) {
layout.isEnabled = YES;
layout.width = YGPointValue(320);
layout.height = YGPointValue(80);
layout.marginTop = YGPointValue(64);
layout.marginLeft = YGPointValue(0);
}];
[self.view addSubview:view];
[view.yoga applyLayoutPreservingOrigin:NO];

然后将top和left给删掉,看看是什么效果:
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.backgroundColor = [UIColor redColor];
[view configureLayoutWithBlock:^(YGLayout * layout) {
layout.isEnabled = YES;
layout.width = YGPointValue(320);
layout.height = YGPointValue(80);
}];
[self.view addSubview:view];
[view.yoga applyLayoutPreservingOrigin:NO];
如果没有设置位置,则其默认起始点是(0,0)。
再次将代码简化:
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.backgroundColor = [UIColor redColor];
[view configureLayoutWithBlock:^(YGLayout * layout) {
layout.isEnabled = YES;
layout.marginTop = YGPointValue(100);
layout.padding = YGPointValue(18);
}];
[self.view addSubview:view];
[view.yoga applyLayoutPreservingOrigin:NO];
padding中设置的值决定了视图的尺寸(width和height是设置值的两倍)。
下面演示如何往View上添加控件:
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.backgroundColor = [UIColor redColor];
[view configureLayoutWithBlock:^(YGLayout * layout) {
layout.isEnabled = YES;
layout.marginTop = YGPointValue(100);
layout.padding = YGPointValue(self.view.frame.size.width/2);
}];
[self.view addSubview:view];
UIView *bottomView = [[UIView alloc] initWithFrame:CGRectZero];
bottomView.backgroundColor = [UIColor yellowColor];
[bottomView configureLayoutWithBlock:^(YGLayout * layout) {
layout.isEnabled = YES;
layout.marginTop = YGPointValue(0);
layout.padding = YGPointValue(8);
}];
[view addSubview:bottomView];
[view.yoga applyLayoutPreservingOrigin:NO];
bottomView的marginTop设置的是0,按正常思维而言应该在view的最上方,但结果却是在中间位置。
那么,在view上再添加一个UIButton会是什么结果呢?
UIView *view = [[UIView alloc] initWithFrame:CGRectZero];
view.backgroundColor = [UIColor redColor];
[view configureLayoutWithBlock:^(YGLayout * layout) {
layout.isEnabled = YES;
layout.marginTop = YGPointValue(100);
layout.padding = YGPointValue(self.view.frame.size.width/2);
}];
[self.view addSubview:view];
UIView *bottomView = [[UIView alloc] initWithFrame:CGRectZero];
bottomView.backgroundColor = [UIColor yellowColor];
[bottomView configureLayoutWithBlock:^(YGLayout * layout) {
layout.isEnabled = YES;
layout.marginTop = YGPointValue(0);
layout.padding = YGPointValue(8);
}];
[view addSubview:bottomView];
UIButton *but = [UIButton buttonWithType:UIButtonTypeCustom];
but.backgroundColor = [UIColor grayColor];
[but addTarget:self action:@selector(selectorBut) forControlEvents:UIControlEventTouchUpInside];
[but configureLayoutWithBlock:^(YGLayout * layout) {
layout.isEnabled = YES;
layout.marginTop = YGPointValue(0);
layout.padding = YGPointValue(50);
}];
[view addSubview:but];
[view.yoga applyLayoutPreservingOrigin:NO];
图中显示,Button的top和bottomView的bottom是在一起的。
以上