这是 WWDC2019 发布的 SwiftUI 布局框架的一些官方示例。
首先为了保证项目的正常运行,需要升级 Mac OS 至 10.15 beta 版,以及 Xcode 使用 Xcode 11 beta。
1.创建项目运行
首先创建一个新的项目,模板可以使用第一个Single View App
,项目名称官方的Demo叫做Landmarks
,勾选上Use SwiftUI
如图。
然后创建项目,点击打开 ContentView.swift
,代码如下:
import SwiftUI
struct ContentView: View {
var body: some View {
Text("Hello World")
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
目前该类声明了两个 struct,第一个是该 View 的实现,第二个是为了实现该 View 的浏览。
然后在 canvas 视图上点击 Resume
(如果找不到,打开 Editor > Editor and Canvas )。
然后修改 View 实现的代码,可以实时看到效果
struct ContentView: View {
var body: some View {
Text("Hello SwiftUI!")
}
}
2、定制TextView
在之前的基础上,按住Command
,并单击 Hello SwiftUI!
,会弹出菜单,选择Inspect
修改属性。
点击之后
修改 Font
为 title
。
然后手动修改UI代码,添加颜色为绿色:
struct ContentView: View {
var body: some View {
Text("Turtle Rock")
.font(.title)
.color(.green)
}
}
接下来在代码中单击文本的声明Text("Turtle Rock")
,可以看到弹出的菜单,点击检查器inspect,把颜色再改回黑色。
这个时候你会发现,Xcode会删除Text("Turtle Rock")
这一行。
3、使用 Stack 去组合 View
这一部分会添加几个视图,并使用 Stack去组合。
单击 Text("Turtle Rock")
,弹出的菜单中选择 Embed in VStack
。
单击Xcode窗口右上角的加号按钮(+)打开库,然后在“Turtle Rock”文本视图后将Text视图拖到代码中的位置。
替换文本为 Joshua Tree National Park
,设置字体为.subheadline
。
然后编辑VStack
的初始化方法,代码修改为 VStack(alignment: .leading) {
使得它左对齐。
然后在 canvas 里面 command 并单击 Joshua Tree National Park
,选择 Embed in HStack
添加一个新的 textView,输入内容 California
,设置字体为 .subheadline
。
通过将 Spacer
添加到包含两个 Text 的水平堆栈,使得布局使用设备的整个宽度,如下:
struct ContentView: View {
var body: some View {
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
HStack {
Text("Joshua Tree National Park")
.font(.subheadline)
Spacer()
Text("California")
.font(.subheadline)
}
}
}
}
Spacer 会使用俯视图所有的空间,彻底的展开,不需要通过指定内容大小等属性。
最后,使用 padding()
修饰符,添加到Stack的实现结束的地方,给界面留一些呼吸的空间。
struct ContentView: View {
var body: some View {
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
HStack {
Text("Joshua Tree National Park")
.font(.subheadline)
Spacer()
Text("California")
.font(.subheadline)
}
}
.padding()
}
}
4、Image 添加图片
这一部分会添加一个独立的原型的自定义图片视图,将遮罩,边框和阴影应用于图像。
将图片添加到资源 asset
目录下。
创建一个新的额 SwiftUI
类,命名为 CircleImage.swift
,并替换其实现如下,使用Image 的初始化方法 Image(_:)
。
struct CircleImage: View {
var body: some View {
Image("turtlerock")
}
}
Image初始化方法之后添加圆形剪裁形状,Circle
可以像这样用做于一个蒙版,或者用作一个试图内的原型的填充。
struct CircleImage: View {
var body: some View {
Image("turtlerock")
.clipShape(Circle())
}
}
然后添加其余的属性,颜色,线宽和半径为10个单位的阴影:
struct CircleImage: View {
var body: some View {
Image("turtlerock")
.clipShape(Circle())
.overlay(
Circle().stroke(Color.gray, lineWidth: 4))
.shadow(radius: 10)
}
}
6.组合成详情 View
在第一个 ContentView 类中插入一个新的 VStack 视图,位置如下:
struct ContentView: View {
var body: some View {
VStack {
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
HStack(alignment: .top) {
Text("Joshua Tree National Park")
.font(.subheadline)
Spacer()
Text("California")
.font(.subheadline)
}
}
.padding()
}
}
}
添加一个 MapView,在新添加的 VStack 的下面,设置 MapView 的 Size, 如下:
struct ContentView: View {
var body: some View {
VStack {
MapView()
.frame(height: 300)
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
仅指定 height 参数的话,View 会自动调整其内容的宽度。在这种情况下,MapView 会扩展以填充可用空间。
点击 Live Preview
实时预览视图。
然后在 MapView 的下方,添加我们上一步实现的 CircleImage
,并且设置向上的位置偏移量。
CircleImage()
.offset(y: -130)
.padding(.bottom, -130)
在最外面的 VStack 的底部添加一个 spacer,把内容整个推到屏幕的上面。
最后:让 MapView 忽略上面的安全距离,在MapView下面插入 .edgesIgnoringSafeArea(.top)
,完整的类实现代码如下:
struct ContentView: View {
var body: some View {
VStack {
MapView()
.edgesIgnoringSafeArea(.top)
.frame(height: 300)
CircleImage()
.offset(y: -130)
.padding(.bottom, -130)
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
HStack(alignment: .top) {
Text("Joshua Tree National Park")
.font(.subheadline)
Spacer()
Text("California")
.font(.subheadline)
}
}
.padding()
Spacer()
}
}
}