Layout and Stacks

直接翻译过来是布局和栈。

视频教程传送门:教程链接 本篇主要介绍SwiftUI中的布局,最终要实现的效果是:

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_Text

App图标的设置

刚开始我想设置图标是不是跟Android一样,在某个清单文件里面设置,比如plist文件,找了半天结果不是,SwiftUI项目的App图标需要在Assets.xcassets这个文件夹里面,设置AppIcon,总共要设置18个各种分辨率的图标(如果分辨率不对,还拖不进去):

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_Text_02


现在有很多的网站都支持导出IOS工程的各种分辨率图标,使IOS开发简便了不少。比如图标工厂

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_控件_03


相比Android可以直接用矢量图标来做App图标,IOS设置图标的方式着实有些麻烦。布局的编写方式

最简便的方式,是在编辑器界面,或者预览界面按住command ,然后选择要包裹的控件:

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_ios_04


ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_Image_05


然后选择Embed开头的选项,就可以将控件包裹进某个布局中,如上面图表中显示的,最常用的布局是HStack,VStack,ZStack,后面的List就是将控件包裹进一个列表,这个列表可以遍历某个集合来生成集合对应的列表视图。

HStack前面的H是Horizontal的缩写,HStack是水平布局,类比于Android里面的LinearLayout,然后把orientation设置成horizontal,Flutter里面的Row。

VStack前面的V是vertical的缩写,故VStack是垂直布局,类比于Android里面的LinearLayout,然后把orientation设置成vertical,Flutter里面的Column。

ZStack前面的Z意思相当于坐标系中的Z轴),所以ZStack是堆叠布局,即屏幕法线方向的布局。类比于Android里面的FrameLayout,Flutter里面的Stack。当然,布局同样可以自己在左边编辑器输入同样的代码来实现同样的效果,比如HStack:

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_ios_06


效果是一样的。

卡面布局的编写

点击右上角的加号,会显示出当前所有可用的控件和Modifier,Modifier就是控件的修改器,可以修改修改控件的各种属性。

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_app_07


ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_Text_08


然后拖一个Text,到已有的Hello World下面,两个Text就会自动组合成一个VStack

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_Text_09


分别按住Command点击两个Text

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_Image_10


选择show SwiftUI Inspector,在弹出的界面中修改两个Text的属性:

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_控件_11


在这个界面对Text修改,其实还是在Text上面添加Modifier。

将上面的Hello world,改成UI Design,修改字体大小为Title,并加粗。

下面的Placeholder改成Certificate颜色改成accent。

这里面的Color(“accent”)调用的Assets.xcassets这个资源文件夹里面名字为accent的颜色资源,所有的资源都已经提前导入了。

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_ios_12


然后同样,在根目录VStack的Inspector中修改对齐方式(Alignment)
,使两个Text左对齐:

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_Image_13


回头看效果图,两个Text组成的VStack应该和一张图片水平排列,点击加号,将图片拖到两个Text右边,就会将VStack和图片组合成一个HStack:

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_ios_14


ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_ios_15


可以看到,图片组件为Image,直接将资源文件夹中的图片名称字符串传入,就能显示该图片。

这个时候VStack和Image挨得很近,要把他们分隔开,分别放置于屏幕两端,就要用到Spacer()

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_ios_16


**Spacer()**的作用,就是占据父容器中的剩余空间。这里的剩余空间,是指父容器的在相应方向上的尺寸,减去其他控件在此方向上的尺寸,再减去每个控件的外边距margin(Android,Flutter,WPF中都有这个概念,SwiftUI里面应该没有margin的概念)。

如果父控件没有硬编码的尺寸,则会将父控件在相应方向上尽可能的拓展,比如上面的例子中,Spacer就将HStack在水平方向上的尺寸拓展到了屏幕的左右边界。

如果有多个Spacer,则这些Spacer将平分父容器中的剩余空间。点击加号,将Card1图片拖到整个HStack下面:

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_Text_17


图片拖入预览框的时候都是默认以原始尺寸来显示的。

效果图中,上面的HStack和下面的Image是有一些间隙的,所以这个时候在他们中间要添加一个Spacer

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_Image_18


Spacer将两边的控件都推到了屏幕的边缘。

到这里,基本元素都具备了,开始添加Modifier,来把这些元素做成银行卡卡面的样子。

首先要约束这个银行卡的尺寸,在顶层VStack的Inspector中,修改它的width,height:

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_Text_19


ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_Image_20


这种直接把尺寸写死的写法就叫硬编码,坏处是尺寸固定,不定适配各种不同尺寸的设备。

这个时候,图片的边框已经超出了外层VStack的边框,所以要改变Image,来适应外层VStack的尺寸:

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_app_21


上面给Image添加了一个resizable()的modifier,这个函数的作用是是Image的尺寸可以调整。如果不加这个modifier,即使将Image用frame来硬编码尺寸也是无效的。
但是只加了resizable()的Image为了适应外层的尺寸,比例是失真的,这时候要添加比例(aspectRatio)来调节图片的显示比例:

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_控件_22


aspectRatio里面的参数是.fill,表示要将图片铺满,不会有空隙,如果是.fit,则会适应高度或者适应宽度,会产生空隙。这两种方式都是以图片原本的尺寸比例还显示的,不会把图片压扁。
给外层VStack加背景色(background)和圆角(conerRadius)

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_Text_23


background的参数是一个View,也就是说可以用任何控件来当做背景。

看上去已经稍微有一些银行卡的样子了。

添加阴影(shadow),增加层次感:

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_ios_24


上面添加的圆角会把VStack进行裁剪,甚至将文字也裁剪掉了一部分,所以要增加一些边距(padding),防止文字被裁剪:

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_ios_25


添加了两个padding,一个是horizontal,也就是水平方向,左右两边,第二个是top顶部。

修改一下卡面背景色,和字体颜色(background,foregroundColor)

修改下面图片的填充样式(aspectRatio),给一个硬编码尺寸,让图片涂满底部:

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_控件_26


到这里已经看上去像是一张银行卡了,下面将多张银行卡堆叠起来。

ZStack包括最外层的VStack:

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_ios_27


ZStack的显示顺序是越后面的控件,显示的位置越靠上,所以在这张卡片底部添加控件,需要写在它的上面:

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_控件_28


上面添加了一个宽高为300,220,背景色为蓝色,圆角为20的空白背景卡片,但是因为它的编写顺序在另一个控件前面,所以另一个控件把它遮挡住了。添加一个**位置偏移(offset)**来将它和它上面的控件错位,就能看到它显示出来了:

ios自定义tabbaritem的图片大小 ios怎么自定义图标布局_ios_29