iOS swiftUI 创建 macos图片 1.0
创建MACOS应用
创建了watchOS
平台的Landmarks
应用后,下一步就是把Landmarks
带到MacOS
平台上。运用之前学到的所有知识,完成在iOS
、watchOS
及macOS
的全平台应用。
在项目工程中添加macOS
编译目标,复用在iOS
应用中的代码和资源,使用SwiftUI
创建macOS
平台上的列表和详情视图。
按照步骤来编译工程,或者下载工程查看完成后的代码。
项目文件第一节 项目中添加macOS
编译目标
项目中添加macOS
编译目标,Xcode
会自动添加一个文件组与一些初始文件,还会生成一个编译运行方案。
步骤1 选择File
->New
->Target
,模板选择页面出现后,选择macOS
选项卡,选中App
模板并点击Next
。这个模板会添加一个新的macOS
编译目标到项目里。
步骤2 在信息表中,输入MacLandmarks
作为项目的名称,设置编程语言为Swift
,界面构建方法为SwiftUI
,然后点击Finish
。
步骤3 设置运行方案为MacLandmarks
-> My Mac
。这样就可以编译并运行macOS
应用。
这个应用的运行依赖一些特性,这些特性在早期的macOS上是不支持的,所以可能需要改变部署目标。
步骤4 在项目导航器中,选择顶部的Xcode
项目,在可用编译运行目标栏中,选择部署目标为10.15
。
步骤5 在MacLandmarks
文件夹中,选择ContentView.swift
文件,打开预览画布,点击恢复(Resume)
,查看预览。SwiftUI
会提供main
视图和它的预览视图提供者,就像iOS
应用,可以预览应用的主窗口。
第二节 共享数据和资源
下一步,复用来自iOS
应用的模型和资源文件到macOS
应用中。
步骤1 在项目导航器中,打开Landmarks
文件夹并选中所有Models
和Resources
文件夹。landmarkData.json
文件包含在教程的启动项目,里面包含了一个新的description
字段,这是之前的教程中所没有的内容。
步骤2 在文件检查器中,为选中的文件设置目标成员关系为MacLandmarks
项目。应用编译时需要访问这些共享资源。要使用新的description
字段,需要在Landmark
结构体中添加一个对应的字段。
步骤3 打开Landmark.swift
文件,添加一个description
属性。因为载入的数据遵循Codable
协议,只需要确保属性名称和json
文件中对应的字段名称一致就可以导入新增的字段数据了。
第三节 创建行视图
对于使用SwiftUI
来构建视图,一般是自底向上的方式,先创建小视图,然后用小视图组合成更大的视图。下面将创建一个列表的行视图。这个行视图包含地标的名称、地理位置、图片以及一个可选的标记,表标这个地标是否被收藏。
步骤1 在MacLandmarks
文件夹下添加一个新的SwiftUI
视图,命名为LandmarkRow.swift
。iOS
应用下也有一个与之同名的文件,重名文件可以通过设置文件的目标成员为适合的App来解决重名的问题。
步骤2 添加一个landmark
属性到LandmarkRow
结构体中,并更新预览视图,让新创建的视图可以在预览视图中展示出来。
步骤3 用VStack
包裹的地标图片视图替换占位文本Text
视图。
步骤4 添加一个包裹在VStack
中的描述地标的文本视图。
步骤5 添加一个收藏指示视图,把它和其它现有的内容用一个Spacer
分割开。Spacer
会把已有的视图推向左边,但是收藏指示视图要放在右边,目前是不可见状态,因为此时还没有图片资源与之对应。
步骤6 从Resources
文件夹下拖动star-filled.pdf
和star-empty.pdf
文件到macOS
应用的Assets.xcassets
文件内。
步骤7 给行视图添加内边距,现在就能够把黄色的收藏标记显示出来了。行视图的内边距可以提高可读性,当把多个行视图集合到列表视图内时,这一点就能很明显的看出来了。
第四节 把行视图组合进列表视图中
使用上一节创建的行视图,创建一个列表视图,用来展示用户了解的所有地标。当showFavoritesOnly
属性为真时,列表中只展示那些被用户收藏的地标。
步骤1 添加一个名为LandmarkList.swift
的新的SwiftUI
视图
步骤2 添加userData
属性作为环境注入对象,并更新预览视图。这样就可以让视图访问全局用户地标数据。
步骤3 创建一个列表,行使用使用landmarkRow
定义的类型。
步骤4 让列表的行可以被用户选中,需要给列表提供一个绑定可选地标成员的关系,并用地标数据自己来标识行。之后会使用这个被选中的地标来展示地标详情页。
步骤5 根据showFavoritesOnly
的状态值以及地标数据是否被用户标记为收藏来决定列表中展示的行的内容。
第五节 创建过滤器来管理列表的展示内容
因为用户可以标记地标为收藏状态,所以需要提供方式让用户只看到自己收藏过的地标。现在要创建一个过滤器视图,使用Toggle
控件给用户提供一个勾选设置,让用户选择是否过滤列表中的非收藏地标,只展示收藏过的地标。
为了让用户可以快速筛选出自己喜欢的地标,这里会添加一下选择器弹出按钮,让用户可以根据地标的不同类别,选择过滤展示自己收藏的地标数据。
步骤1 添加一个名为Filter.swift
的SwiftUI
视图。
步骤2 添加userData
属性作为环境注入对象,并更新预览视图。
步骤3 用Toggle
控件来展示布尔值showFavoritesOnly
属性,并给它一个恰当的标签文本。
当用户选择勾选框时,列表视图也会跟着一起刷新展示,因为它们都绑定了同一上环境注入对象中的值showFavoritesOnly
。除此之外,还可以使用地标的类别来定义额外的过滤条件。
步骤4 创建FilterType
类型,用来存放地标的类别以及类别对应的名称。确保FilterType
遵循Hashable
协议,这样FilterType
就可以被用在选择器。FilterType
中的名称属性可以展示在选择器中,让用户选择过滤哪一种类别的地标。
步骤5 定义一个all
类型用来表示不使用任何地标类别过滤。这个额外的过滤类别要求FilterType
有一个特殊的初始构建器,用来处理类别为空的初始化场景。
遵循CaseIterable
和Identifiable
协议,让FilterType
可以做为ForEach
的初始化入参,之后就可以使用这个FilterType
类型了。
步骤6 遵循CaseIterable
协议,给列表提供所有可能的类别。
步骤7 遵循Identifiable
协议并定义一个id
属性。
步骤8 在Filter.swift
中,给Filter
视图添加一个选择器,选择器使用一个FilterType
的绑定用来记录用户选择,FilterType
的名称用来表示用户在选择器菜单中的选项。使用FilterType
的绑定关系可以让父视图观察到用户的选择。
步骤9 返回到列表视图,添加FilterType
绑定关系。对于过滤器视图来说,这允许它和父视图共享变量filter
。
步骤10 更新列表行的创建逻辑,让它包含类别过滤功能。查找那些与用户选中的过滤类别相匹配的地标类别,或者任何用户选择的特色类别地标。