天天看點

Yoga

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];

Yoga

然後将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];

Yoga

如果沒有設定位置,則其預設起始點是(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];

Yoga

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];

Yoga

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];

Yoga

圖中顯示,Button的top和bottomView的bottom是在一起的。

以上