前言
未来大前端是一个趋势,对于布局方面盒子布局FlexBox
也是趋势,我们iOS开发中,怎么使用盒子布局呢?
1. iOS 原生布局
1.1 iOS布局介绍
在iOS开发中常用的是下面2种
Frame
frame`布局是设置视图的坐标,依赖于父视图,属于`相对布局
Auto Layout
Auto Layout
布局是苹果出的一种布局方式,原理是通过Cassowary
算法进行计算 Cassowary
是上世纪90年代诞生的一种用于解决用户界面布局问题的算法,它通过将布局问题
抽象成线性等式
或不等式约束来
进行求解,而我们要了解的Auto Layout
就是对Cassowary算法
的一种实现。通过视图控件之间的关系进行布局,但是本身语法很长
,我们通常会使用三方的框架进行实现比如Masonry等
1.2 Auto Layout 原理
我们使用storyboard
进行演示,我们确定一个视图的布局
我们上面的蓝色视图就可以依赖
下面黄色视图进行布局,设置等宽等高
左对齐
底部距离黄色的头部距离
当我们旋转屏幕
的时候,根据它们的依赖关系
也是一样
这就是自动布局
,依赖我们的确定的视图,根据依赖关系
进行布局。
使用Frame
表示
UIView *view1 = [[UIView alloc]initWithFrame:CGRectMake(20, 350, 100, 60)];
view1.backgroundColor = [UIColor orangeColor];
[self.view addSubview:view1];
UIView *view2 = [[UIView alloc]init];
view2.backgroundColor = [UIColor greenColor];
CGRect frame = CGRectMake(0, 0, 0, 0);
frame.size = view1.frame.size;
frame.origin.x = view1.frame.origin.x;
frame.origin.y = view1.frame.origin.y - view1.frame.size.height -40;
view2.frame = frame;
[self.view addSubview:view2];
但是我们旋转屏幕
的时候,不是我们想要的结果,这就是绝对布局的一些不好的地方
自动布局的原理大概就是这样,控件件是依赖关系
,不是绝对关系
2. YogaKit
2.1 FlexBox 简单介绍
FlexBox
是一种盒子布局方式
,在前端
和页面应用比较广泛,布局的方式主要是row
,column
, stack
3个方向进行布局,控件类似在一个盒子里面,弹性布局.
FlexBox
把每个视图,都看作一个矩形盒子
,拥有内外边距
,沿着主轴方向
排列,并且,同级的视图之间没有依赖
。
采用flex布局的元素
,称为Flex容器
,简称’容器‘
,它所有元素自动成为容器成员,称为Flex项目
。弹性布局和方向没有关系,它是一维布局。
2.2 YogaKit
YogaKit
是facebook
开源的一个关于盒子布局的框架,适用于整个大前端,这里我们主要介绍下iOS中yogakit的使用,查看GitHub上YogaKit[1]
我们新建一个项目pod 'YogaKit'
我们看下携程的首页,菜单布局
我们分析下怎么样布局,布局的方式有很多,我们整体分为4个板块
,从上向下
布局。前2个布局样式我们可以水平布局
,也可以竖直布局
,第三个某块分为2个部分,右边的可以水平布局
,也可以水平后竖直布局,最后一个水平布局
同时我们可以发现组件之间有间距,itemButton
之间也有间距。这里要区分下padding
和margin
的区别。padding
类似我们iOS中的UIEdgeInsets
,约束自己的内部边距,margin
则相当于距外部的边距
红色的是margin
,白色区域相当于padding
我们这里设置
#define paddingNo 3
#define marginNo .5f
#define columnNo 3
#define btnHeight 62
#define btnWidth ((UI_SCREEN_WIDTH - paddingNo*2 - columnNo*marginNo*2) / columnNo)
复制代码
2.3 使用
UIView的拓展 继续查看YGLayout
,YGLayout
的isEnabled
默认是no
,要手动开启,同时要在主线程布局UI
。
2.3.1 第一模块和第二模块
我们把按钮创建抽出来
- (UIButton *)createBtnWithTitle:(NSString *)title BackgroundColor:(UIColor *)color ImageIndex:(int)index {
UIButton *commonBtn = [[UIButton alloc] init];
[commonBtn setBackgroundImage:[UIImage imageNamed:[NSString stringWithFormat:@"btnImg_%d", index]] forState:UIControlStateNormal];
commonBtn.backgroundColor = color;
[commonBtn setTitle:title forState:UIControlStateNormal];
[commonBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
commonBtn.titleLabel.font = [UIFont systemFontOfSize:15];
commonBtn.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
[commonBtn setTitleEdgeInsets:UIEdgeInsetsMake(index==13?-btnHeight:0, 10, 0, 0)];
[commonBtn addTarget:self action:@selector(commonBtnAction:) forControlEvents:UIControlEventTouchUpInside];
return commonBtn;
}
- (void)commonBtnAction:(UIButton *)sender {
sender.selected = !sender.selected;
UIViewAnimationTransition tra = sender.selected?UIViewAnimationTransitionFlipFromLeft:UIViewAnimationTransitionFlipFromRight;
[UIView animateWithDuration:.35 animations:^{
[UIView setAnimationTransition:tra forView:sender cache:YES];
}];
}
实现模块一的效果
我们最后设置下主界面的layout
配置,同时主动调用applyLayoutPreservingOrigin
:父视图执行布局
计算并使用结果更新层次结构中视图的帧
我们把容器的主轴方向改为column
,不设置高度的话会容器的元素会自动撑满
设置高度
,可以达到我们row
的效果布局,默认容器的布局方向为纵向。
第二模块类似
2.3.2 模块三和四
对于模块3我们直接添加会有问题
我们把右边部分当成一个模块
模块4类似
当我们调整个数的时候也很方便
我们也可以实现一个自定义的九宫格类型
参考资料
YogaKit: https://github.com/facebook/yoga
代码地址:
https://github.com/DHFLoveWL/YogaKitDemo)
来源:潜水的鱼儿
https://juejin.cn/post/7039635424947470343
-End-
最近有一些小伙伴,让我帮忙找一些 面试题 资料,于是我翻遍了收藏的 5T 资料后,汇总整理出来,可以说是程序员面试必备!所有资料都整理到网盘了,欢迎下载!
面试题
】即可获取