一、创建项目并体验画布

① 系统要求

  • 创建 SwiftUI 项目工程,体验画布、预览模式和 SwiftUI 模板代码;
  • 要想在 Xcode 中预览画布中的视图,或者与画布中的视图进行交互,需要 Mac 系统版本号不低于 macOS Catalina 10.15。

② 步骤

  • 打开 Xcode,在启动页面点击创建新工程,或者在菜单中选择文件->新建->项目:

  • 在项目模板选择器中,选择 iOS 作为项目平台,选项单视图应用(App)作为项目模板,并点击下一步(Next):

  • 输入项目名称 FirstSwiftUI,选择 SwiftUI 作为用户界面的创建方式,并点击下一步 Next,在磁盘目录下选择一个位置用来存放新创建的工程项目:

  • 工程创建好并打开后,在文件导航器中,选择 ContentView.swift 文件,可以浏览一下 SwiftUI 视图的组成结构。默认情况下,SwiftUI 的视图文件包含两个结构体 Struct:
    • 第一个结构体遵循 View 协议,描述视图的内容和布局;
    • 第二个结构体声明为第一个视图的预览视图。

  • 在**画布(Canvas)上,点击恢复(Resume)**按钮可以显示预览视图,也可以使用快捷键 Command+Option+P(如果工程中没有出现画布 Canvas,可以选择菜单:编辑器 Editor -> 编辑器和画布 Canvas,打开画布进行预览):

  • 在 body 属性内部,修改文字 Hello, world! 为其它的不同的文字,当在改变代码的同时,预览视图也会实时的更新对应的内容变化:

二、定制文本视图 Text View

① 通过修改代码来改变视图的显示样式

  • 可以通过修改代码来改变一个视图的显示样式,也可以通过检查器获取视图可修改属性,然后再写对应的代码改变样式。在创建应用的过程中,可以同时使用源码编辑器、画布或者检查器,无论当前使用的是哪一个工具编辑视图,代码会保持和这些编辑器展示的样式一致:

② 使用检查器来定制视图的显示样式

  • 在预览视图中,按下 Command 键的同时点击控件,会弹出一个编辑弹层,然后选择检查器 Inspect, 编辑弹层显示所有可以定制的视图属性,选中的控件不同,可以定制的属性集合也不相同:

  • 使用检查器把文字更改为Turtle Rock,也就是在应用中显示的第一个地标的名称:

  • 改变字体修改器为 Title,使用系统字体修饰文字,可以自动按照用户在设备中设置的字体偏好大小进行调整。定制 SwiftUI 视图所调用的方法被称为视图修改器 Modifiers,修改器在原视图的基础上修改部分显示样式和属性,返回一个新的视图,这样就可以让多个修改器串连进行,形成水平方向的链式调用,或者垂直方向的堆叠调用:

  • 手动在代码中添加 foregroundColor(.green) 属性修改器,就会把文字的颜色调整为绿色。代码是决定视图样式的根本,当我们使用检查器来改变或移除一个属性修改器时,Xcode 也会在代码编辑器中同步改变或移除对应的修改器代码:

  • 在代码编辑器中,按下 Command 的同时点击 Text 单词也可以属性弹窗,从中选择检查器后,再点击 Color 弹出菜单,选择继承 Inherited,让文字的颜色恢复成原来的黑色:

  • 当我们移除 foregroundColor(.green) 时,Xcode 会自动更新代码来反映视图的实际显示状况:

三、使用栈来组合视图

  • 上文中创建了标题视图,接下来要添加一些文本视图来描述地标所在州及所在公园的名称等其它详细信息:

  • 创建 SwiftUI 视图就是在 body 属性中描述视图的内容、布局及行为,但 body 属性只返回单个视图,这时组合多个视图时可以把它们放入一个栈中,通过水平、垂直、前后嵌套多个视图完成视图组合,做为一个整体在 body 属性中返回。
  • 现在使用一个垂直栈,把标题放在包含公园详情的水平栈的上方,在水平栈中,布局公园详情相关的内容,可以使用 Xcode 提供的结构化布局来把视图嵌套在容器视图中。
  • ① 按下 Command 键的同时,点击 Text 视图的初始化代码打开结构化编辑弹窗,然后选择把控件嵌套在垂直栈中 Embed in VStack,在栈中添加 Text View 控件可以从组件中直接拖进栈中完成:

  • ② 点击 Xcode 右上角的 + 号,托动一个 Text 控件到指定位置,代码立即就会在编辑器中补全;

  • ③ 把 Text 视图的占位文本修改为 Joshua Tree Nation Park,视图会自动调整位置布局;
  • ④ 设置位置控件的字体为子标题样式:
struct ContentView: View {var body: some View {VStack {Text("Turtle Rock").font(.title).padding()Text("Joshua Tree Nation Park").font(.title2)}}
}

  • ⑤ 设置 VStack 初始化参数为左对齐内部的子视图,默认情况下,栈会把内部视图在自己的主轴上居中对齐,并自动计算各子视图的间距。下一步要添加一个 Text 控制用来描述公园的状态,它水平排列在位置信息的右边;

  • ⑥ 在画布内,command 按下的同时点击位置视图,在弹出的菜单中选择嵌入到水平栈中 Embed in HStack;

  • ⑦ 在位置控件的后面加一个公园状态的 Text 视图,并把占位文字改为 California,字体设置为子标题样式;

  • ⑧ 为了水平布局使用整个屏幕宽度,在位置控件和公园状态控件中间添加一个 Spacer 控件,用来填充两个控件中间的空白部分,并把两个控件分别顶向屏幕的两侧;Spacer 是一个可以伸缩的空白控件,它负责占用其它控件布局完成后剩下的所有空间;

  • ⑨ 使用 padding() 修改器给地标信息内容视图整体加内边距;

四、创建自定义图像视图 Image

  • 有了地标名称、地标位置及状态视图,下一步再添加一个地标图片视图,这个图片视图将自定义遮罩 mask、边框 border 和阴影 shadow;可以从控件加中拖一个 Image 到画布,或直接写代码到代码编辑器中。
  • 在项目资源文件中找到 turtlerock.png 图片,把它拖入资源编辑器 asset catalog editor 中,Xcode 会创建一个新的图片集来存放这个图片,然后创建一个 SwiftUI 视图:

  • 选择文件->新建->文件,打开模板选择器,在用户界面(User Interface)板块下,选择 SwiftUI View 并点击下一步,命名为 CircleImage.swift,并点击创建(Create),现在已经准备好插入图片并修改布局来满足设计目标:

  • 用 Image 替换 Text,并使用 turtlerock 图片初始化 Image 视图;

  • 添加 clipShape(Circle()) 修改器到 Image,给图片添加圆形剪切效果;Circle 是一个形状,它可以被用作遮罩、也可以是圆圈,还可以是圆形填充视图;
  • 创建另一个灰色的圆圈并把它作为一个浮层添加到图片上,相当于给图片加了一个灰色边框;
  • 给视图添加半径为 10 的阴影;

  • 把圆形边框的颜色改成白色,就完成了自定义图片视图的创建:

五、UIKit 视图与 SwiftUI 视图混合使用

  • 现在要创建一个地图视图,可以使用 MapKit 中的 MKMapView 视图类来渲染地图,要在 SwiftUI 中使用 UIView 及其子类,需要把这些 UIView 包裹在一个遵循 UIViewRepresentable 协议的 SwiftUI 视图中,SwiftUI 中也包含适配 WatchKit 和 AppKit 的类似的协议:

  • 创建一个自定义视图用来容纳和显示 MKMapView:
    • 选择文件->新建->文件,选择 iOS 平台,选择 SwiftUI View 模板,并点击下一步(Next),命名文件为 MapView.swift,并点击创建(Create);
    • 代码中导入 MapKit 引用,声明 MapView 遵循 UIViewRepresentable 协议,UIViewRepresentable 协议要求实现两个方法 UIView(context:) 和 updateUIView(_:context:),第一个方法用来创建 MKMapView,第二个方法用来配置视图响应状态变化;
    • 替换 body,用 makeUIView(context:) 方法来代替,创建并返回一个空的 MKMapView;
    • 创建方法 updateUIView(_:context:),在方法内部设置地图视图的坐标为 Turle Rock 的中心。在静态模式下预览时,只会渲染 SwiftUI 视图的部分,因为 MKMapView 是 UIView 的子类,所以需要切换到实时预览模式下才能看到地图被完全渲染出来;

  • 点击 Live Preview(实时预览)按钮,可能需要点击 Try Again 和 Resume 按钮来激活预览模式的切换,切换到实时预览模式下不久就可以看到指定地标所在的地图位置:

六、组合地标详情页

  • 我们已经完成了创建一个地标详情页所需要的各种子视图元素:名称、地点、圆形图片以及位置地图,现在可以把这些视图元素组合在一起形成地标详情页的整个视图:

  • 在项目工程浏览器中选择 ContentView.swift 文件;
  • body 属性中嵌入一个 VStack 视图,它内部包含另一个 VStack 视图,内部的 VStack 视图又包含三个 Text 视图;
  • 在外层 VStack 的顶部添加自定义的地图视图 MapView,并使用 frame(width:height:) 设置视图大小。当只指定高度时,宽度会自动计算为父视图的宽度,在这里就是屏幕宽度;
  • 点击 Live Preview 按钮进入实时预览模式,查看地图渲染情况,在实时预览模式下可以编辑视图,最新的改动也可以实时的刷新出来;
  • 在 MapView 后面再添加一个 CircleImage 视图;
  • 为了让图片视图叠放在地图视图的上面,可以设置图片视图的垂直偏移量为 -130,图片视图的底部内边距也为 -130,这个效果就是把图片垂直上移了 130,同时和下面的文字区域留出了 130 的空白分隔区;
  • 在外层 VStack 内部的最下面加上 Spacer,可以让上面的视图内容顶到屏幕的上边;
  • 为了让地图的视图内容显示在状态栏的下方,可以给 MapView 添加 edgesIgnoringSafeArea(.top) 修改器,这可
  • 以让它在布局时忽略顶部的安全区域边距;

七、总结

  • 在声明自定义 SwiftUI 视图时,视图布局要声明 body 属性中;View 协议中要求实现 body 属性,每一个 SwiftUI 视图都遵循 View 协议。
  • 有如下代码布局,那么运行视图效果是什么样?
struct ContentView: View {var body: some View {CircleImage()VStack(alignment: .leading) {Text("Turtle Rock").font(.title)Text("Joshua Tree Nation Park")}}
}

  • 从 body 属性中返回三个视图:
VStack(alignment: .leading) {Text("Turtle Rock").font(.title)Divider()Text("Joshua Tree Nation Park")
}
  • 修改器每次都是返回一个新的对象,所以多个修改器可以通过链式调用,配置视图时,使用修改器的方式如下:
Text("Turtle Rock").font(.title).foregroundColor(.purple)
  • 完整示例:SwiftUI 之如何创建和组合视图。

SwiftUI之深入解析如何创建和组合视图相关推荐

  1. SwiftUI之深入解析如何创建列表展示视图和列表如何导航跳转新页面

    一.前言 地标详情页视图已经创建完成,我们需要提供一种方式让用户可以查看完整的地标列表,并且可以查看每一个地标的详情.地标详情页视图的创建,请参考我的博客:SwiftUI之深入解析如何创建和组合视图. ...

  2. SwiftUI基础——创建并组合视图

    Swift UI 基础 今天开 2020 年的 WWDC 了,所以来学习一下 Apple 的 app 开发吧.

  3. SwiftUI之深入解析如何处理特定的数据和如何在视图中适配数据模型对象

    一.前言 阅读了我的前两篇博客的朋友,应该都熟练掌握了 SwiftUI 如何创建一个任何相关信息的展示视图和各个视图之间的相互组合,以及动态生成一个展示相关信息的可滚动列表,用户可以点击列表项去查看其 ...

  4. SwiftUI之深入解析如何绘制徽章视图的路径和形状

    一.创建徽章视图 创建徽章前需要使用 SwiftUI 的矢量绘画 API 创建一个徽章视图: 选择文件 -> 新建 -> 文件,然后从 iOS 文件模板列表中选择 SwiftUI View ...

  5. SwiftUI之深入解析高级动画的几何效果GeometryEffect

    一.前言 在我的博客 SwiftUI之深入解析高级动画的路径Paths 中,已经了解了 Animatable 的协议,以及如何使用它来动画路径.接下来,我们将使用相同的协议来动画变换矩阵,使用一个新的 ...

  6. android 如何实现无限列表,在Android中解析和创建无限/无限级别的List /子列表中的XML...

    在我的Android Application的服务器端应用程序也由我开发.在这个应用程序Android应用程序从服务器请求一些XML并解析它. XML包含描述应用程序中应该有多少标签的信息,并且每个标 ...

  7. SwiftUI之深入解析高级动画的路径Paths

    一.前言 本文将深入探讨一些创建 SwiftUI 动画的高级技术,讨论 Animatable 的协议,它可靠的伙伴 AnimatableData,强大但经常被忽略的 GeometryEffect 以及 ...

  8. SwiftUI之深入解析@StateObject、@ObservedObject和@EnvironmentObject的联系和区别

    一.@State 属性包装器 ① 什么是 @State 属性包装器? 状态在任何现代应用程序中都是不可避免的,但在 SwiftUI 中,重要的是所有的视图都是它们状态的简单函数,我们不需要直接改变视图 ...

  9. java解析dxf文件_浅析JVM方法解析、创建和链接

    一:前言 上周末写了一篇文章<你知道Java类是如何被加载的吗?>,分析了HotSpot是如何加载Java类的,干脆趁热打铁,本周末再来分析下Hotspot又是如何解析.创建和链接类方法的 ...

最新文章

  1. ActionRequestValidationException[Validation Failed: 1: script or doc is missing
  2. 使用eclipse 进行 Cesium 开发
  3. c语言:将一个二维数组行和列的元素互换,存到另一个二维数组中。
  4. python邮件发送csv附件_Python2.7 smtplib发送带附件邮件报错STARTTLS解决方法
  5. linux windows 丢失,Win10预览版9879硬盘丢失的Linux解决方案
  6. LintCode 375. 克隆二叉树(深复制)
  7. 红外遥控c语言,NEC协议红外遥控器
  8. Mac的反编译工具一:otool (objdump工具的OSX对应工具)。
  9. sklearn决策树特征权重计算方法
  10. UML核心元素--参与者
  11. xammp怎么写php,xampp怎么运行php源码?xampp如何运行php项目?
  12. 互联网+AI,云反射弧如何成为人工智能发展的下一个重点
  13. Python自动化测试框架我到底应该学哪一个?
  14. 户外佩戴哪款耳机好、户外运动耳机推荐
  15. 进制数的转换方法大全
  16. PyGobject(十九)布局容器之Alignment
  17. 汇编指令CLI/STI
  18. ajax远程调用,jquery中的ajax方法怎样通过JSONP进行远程调用
  19. 他山之石,可以攻玉:认知科学中的迭代模型,何以缓解语言迁移
  20. Python主要用来做什么?

热门文章

  1. AIX卷管理介绍以及利用空闲PP来创建文件系统
  2. day17-jdbc 6.Connection介绍
  3. 解决UIScrollView把uitableviewcell的点击事件屏蔽
  4. iOS开发蓝牙 蓝牙4.0的各种踩过的坑,希望你们少踩点
  5. core data firing fault
  6. 将上传图片打上防伪图片水印并写入数据库
  7. 7-5 密码锁 (10 分)
  8. 广东金融学院计算机期末考试,关于2018-2019学年第二学期录入期末成绩的通知
  9. 蔬菜名称大全500种_东莞市区常见野生植物大全——草本植物篇(一)
  10. 默认以管理员启动_如何始终以管理员身份运行 CMD 命令提示符和 PowerShell