主业iOS/PHP,副业啥都玩,QQ:705719110,欢迎来撩!

iOS 上的 FlexBox 布局

iOS开发 随风 184℃ 0评论

最近看到一个flexbox布局方式的跨平台实现,没错,就是facebook的Yoga,也看了一下iOS上的,很多分都以分析各种性能开端,我这里只是介绍一下,不做比较,全看个人选择~
闲来理解一下flexbox,我在之前的RN系列中介绍过一些,可以去看看 flexbox布局与React Native

flexbox简介

采用 flexbox 布局的元素,称为 flex container。flex container 的所有子元素,称为 flex item。

Flex Container

flexbox 的一个特点,就是视图之间,是没有依赖的。flex item 的排布,就依赖于 flex container 的属性设置,而不用相互之间进行设置。

Flex Direction

flexbox 有一个 主轴(main axis) 和 侧轴(cross axis)的概念。侧轴垂直于主轴。
它们可以是水平,也可以是垂直。主轴默认为 Row , 侧轴默认为 Column:

flex direction 决定了 flex containner 内的主轴排布方向。主轴默认为 Row (从左到右):

同时,也可以设置 RowRevers(从右至左):

Column(从上到下):

ColumnRevers(从下到上):

Flex Wrap

flex wrap 决定在轴线上排列不下时,视图的换行方式。flex wrap 默认设置为 NoWrap,不会换行,一直沿着主轴排列到屏幕之外:

设置为 Wrap ,则空间不足时,自动换行:

设置 WrapReverse,则换行方向与 Wrap 相反:

这是一个非常有用的属性。比如典型的九宫格布局。

Display

Display 选择是否计算它,默认为 Flex. 如果设置为 None 自动忽略该视图的计算。在根据逻辑显示 UI 时,比较有用。按照一般做法,多个 icon 互相连成一排,根据身份去设置不同的距离,同时隐藏其他 icon ,比较的麻烦。iOS 最好的办法是使用 UIStackView ,这又有版本兼容等问题。而使用 flexbox 布局,当不是某个身份时,只要设置 Display 为 None,就不会被纳入 UI 计算当中。

Justify Content

Justify Content 用于定义 Flex Item 在主轴上的对齐方式:FlexStart(主轴起点对齐),FlexEnd(主轴终点对齐),Center(居中对齐)。还有SpaceBetween(两端对齐):

设置两端对齐,让 Flex Item 之间的间隔相等。SpaceAround(外边距相等排列):

让每个 Flex Item 四周的外边距相等。

Align Items

Align Items 定义 Flex Item 在侧轴上的对齐方式。Align Items 可以和主轴对齐方式 Justify Content 一样,设置FlexStart ,FlexEnd,Center,SpaceBetween,SpaceAround 。Align Items 还可以设置 Baseline(基线对齐):

如图所示,它是基于 Flex Item 的第一行文字的基线对齐。如果 Baseline 和 Flex Item 的行内轴与侧轴为同一条,则该值与 FlexStart 等效。 其它情况下,该值将参与基线对齐。Align Items 还可以设置为 Stretch:

Stretch 让 Flex Item 拉伸填充整个Flex Container。Stretch会使Flex Item的外边距在遵照对应属性限制下,尽可能接近所在行或列的尺寸。如果 Flex Item 未设置数值,或设为 auto,将占满整个Flex Container的高度。

Align Content

Align Content 也是侧轴在 Flex Item 里的对齐方式,只不过是以一整个行,作为最小单位。注意,如果Flex Item只有一根轴线(只有一行的Flex Itme),该属性不起作用。调整为 FlexWrap 为 Wrap,效果才显示出来:

Flex Item

在上面说完了 Flex Container 的属性,终于说到了 Flex Item. Flex Container 里的属性,都是作用于自己包含的 Flex Item,Flex Item 的属性,都是作用于自己本身。

AlignSelf

AlignSelf 可以让单个 Flex Item 与其它 Flex Item 有不一样的对齐方式,覆盖 Align Items属性。默认值为auto,表示继承Flex Container的Align Items属性。如果它本身没有Flex Container,则等同于Stretch。

FlexGrow

FlexGrow 可以设置分配剩余空间的比例。即如何扩大。FlexGrow 默认值为 0,如果没有去定义 FlexGrow,该布局是不会拥有分配剩余空间权利的。
例如:整体宽度 100 , sub1 宽为 10 ,sub2 宽为 20 ,则剩余空间为 70。设置 flexgrow 就是分配这 70 宽度的比例。
再说比例值的问题:如果所有 Flex Item 的 FlexGrow 属性都为 1 ,如果有剩余空间的话,则等分剩余空间。如果一个 Flex Item 的 FlexGrow 属性为 2,其余 Flex Item 都为 1 ,则前者占据的剩余空间将比其他 Flex Item 多 1 倍。

FlexShrink

与 FlexGrow 处理空间剩余相反,FlexShrink 用来处理空间不足的情况。即怎么缩小。FlexShrink 默认为1,即如果空间不足,该项目将缩小。如果所有 Flex Item 的 FlexShrink 属性都为 1,当空间不足时,都将等比例缩小。如果一个 Flex Item 的 FlexShrink 属性为 0 ,其余 Flex Item 都为1,则空间不足时,FlexShrink 为 0 的前者不缩小。

FlexBasis

FlexBasis 定义了在分配多余的空间之前, Flex Item 占据的 main size(主轴空间)。浏览器根据这个属性,计算主轴是否有多余空间。FlexBasis 的默认值为 auto,即 Flex Item 的本来大小。

YogaKit的简单使用

我采用的是Pod安装

swift没问题,OC安装之后编译可能会报错:“Swift Language Version” (SWIFT_VERSION) build setting must be set to a supported value for targets which use Swift,这是因为pod中的库没有选择swift版本号,解决方法看下图,选择一个当前对应的swift版本就好了

YGLayout

整个 YogaKit 的关键,就在于 YGLayout 对象当中。通过 YGLayout 来设置布局属性。
在 UIView+Yoga.h 的文件里:

可以看到一个名为 yoga 的 YGLayout 只读对象,和 configureLayoutWithBlock:(YGLayoutConfigurationBlock)block 方法,并且还使用了 NS_SWIFT_NAME() 来定义在 Swift 里的方法名。这样我们就可以直接使用 UIView 的实例对象,来直接设置它对应的布局了。

isEnabled

YGLayout.h 里是这么定义 isEnabled 的。

isEnabled 默认为 NO,需要我们在布局期间设置为 YES,来开启 Yoga 样式.

applyLayoutPreservingOrigin

头文件:

简单来说,就是用于执行 layout 计算的。所以,一旦在布局代码完成之后,就要在根视图的属性 yoga 对象上调用这个方法,应用布局到根视图和子视图。

案例一

布局的效果如下:

案例二

布局的效果如下:

案例三

布局的效果如下:

案例四

布局的效果如下:

转载请注明:怼码人生 » iOS 上的 FlexBox 布局

喜欢 (0)
发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址