注册

iOS swiftUI 创建 macos图片 1.1

第六节 组合列表视图与过滤器视图

创建一个组列过滤器和列表的视图。为过滤器提供新的状态信息,同时绑定地标选择到主视图的父视图上。

section 6

步骤1 项目中添加一个新的SwiftUI视图,命名为NavigationPrimary.swift

步骤2 声明一个FilterType状态。这个状态会被绑定到过滤器和列表视图中。

section 6 step2

步骤3 添加过滤器视图并绑定FilterType状态。现在预览是失败的,因为过滤器依赖环境中的用户数据,下一步会处理这块儿。

section 6 step3

步骤4 注入用户数据对角到环境中。导航主视图是不直接需要用户数据的,但它的子视图需要。为了可以进行预览,把用户数据作为环境对象注入到导航主视图中。

section 6 step4

步骤5 添加一个绑定到当前选中地标的关系。

步骤6 添加地标列表视图,并把它绑定到选中的地标和过滤器状态上。预览视图中选中第二个选项,因为输入数据是landmarkData[1]作为用户选中的地标输入数据。

section 6 step6

步骤7 限制导航视图的宽度,防止用户让它变的太宽或太窄。

section 6 step7

第七节 复用CircleImage

有时只需要经过稍微修改,就可以跨平台复用一些视图。当构建macOS平台的地标详情页视图时,会复用iOS版地标应用中的CircleImage视图。为了适配macOS平台下的不同布局要求,会添加一个参数来控件阴影半径。

section 7

步骤1 在项目导航栏中选中Landmarks -> Supporting Views并选择CircleImage.swift文件。

section 7 step1

步骤2 把CircleImage.swift文件添加到时MacLandmarks编译目标。

section 7 step2

步骤3 在CircleImage.swift文件中,修改结构体,使用新的阴影半径参数。通过给新参数提供默认值,可以确保iOSwatchOS平台的应用都能与原来保持一致,同时还能在macOS平台上使用。

section 7 step3

第八节 为macOS扩展MapView

类似于CircleImage,这里要在macOS上复用MapView。然而,MapView要做更大的改动,因为MapView使用的是MapKit依赖于UIKit框架。在macOS平台上使用MapKit需要依赖于AppKit框架,所以需要添加编译器指令,让编译过程在macOS目标上进行正确的依赖。

section 8

步骤1 在项目导航器中,选择Landmarks -> Supporting Views,选中MapView.swift文件。

步骤2 把MapView.swift文件添加到MacLandmarks编译目标上。此时Xcode会报错,因为MapView使用了UIViewRepresentable协议,这个协议在macOS SDK里是没有的。下面的步骤中,会使用NSViewRepresentable协议来扩展MapView,让它能在macOS平台上使用。

section 8 step2

步骤3 插入条件编译指令,用来指定特定平台行为。用条件编译的两个条件分支把协议UIViewRepresentableNSViewRepresentable协议的遵循分开。

步骤4 使用条件编译,把在iOS平台上要实现的协议UIViewRepresentable及协议方法makeUIViewupdateUIView放在MapView的扩展实现中,这样就把MapKit的平台依赖性解耦了。

步骤5 添加在macOS平台上的NSViewRepresentable协议遵循。与UIViewRepresentable协议一样,NSViewRepresentable协议的实现也可以使用主类中的方法。

section 8 step5

第九节 构建详情视图

详情视图展示用户选中的地标信息。创建一个类似iOS平台地标应用的地标详情视图,不同之处在于,macOS平台有不同的数据表示方法,这就需要针对macOS平台对详情视图作一些裁剪,复用一些之前调整过的视图。

section 9

步骤1 项目中添加一个新的视图,命名为NavigationDetail.swift,并添加一个landmark属性。初始化详情视图时会使用landmark属性来指定详情页展示的地标信息。

步骤2 在NavigationDetail.swift内部创建一个滚动视图,滚动视图中包含一个VStackVStack中又包含一个HStack,HStack中展示关于地标的图片CircleImageText地标文本信息。通过设置VStack的最大最小宽度,确保展示的内容保持一定的宽度,以适合用户阅读。跨平台复用视图是非常方便的,定制一下CircleImage视图,以满足当前的布局要求。

section 9 step2

步骤3 把输入的图片变为可缩放,并设置图片按视图大小展示,这样可以让CircleImage视图的大小与Text块文本的大小看上去比较匹配。这种修改方法不需要调整CircleImage的内部实现。

section 9 step3

步骤4 调整阴影半径,以匹配更小的图片。这个修改依赖之前对CircleImage视图所作的参数化改造。

section 9 step4

用户使用按钮标记一个地标是否被收藏。为了让这个动作生效,需要访问用户数据中的对应变量。

步骤5 添加用户数据对应的环境对象,并创建一个基于当前选中地标的存储属性landmarkIndex

section 9 step5

步骤6 添加一个按钮,水平方式对齐地标名称,使用星星图标,并在点击时可以切换用户对这个地标的收藏状态。当用户修改地标数据时,在用户数据中查找被修改的地标数据,并用最新的数据更新原来的数据,让数据保持最新状态。

section 9 step6

步骤7 在分割区载下再添加一个地标的信息,对应数据中新增的字段description

section 9 step7

预览视图中标题块会被挤到左边,因为描述内容比较多,把水平方向的宽度撑满了。

步骤8 在详情视图顶部插入地图,调整地图的偏移,让地图和其它内容有一定区域的重叠。地图占满视图全宽,因此会把详情文本挤到预览视图的底部看不到的位置,但它实际上是存在的。

section 9 step8

步骤9 导入MapKit并添加一个Open in Maps的按钮,当按钮被点击时,打开地图应用并定位到地标位置。

section 9 step9

步骤10 把Open in Maps按钮叠放在地图的右下角。

section 9 step10

第十节 把主视图和详情视图组合起来

已经构建了所有的视图元素,把主视图和详情视图组合起来,共同构成ContentView

section 10

步骤1 在MacLandmarks文件夹中,选择ContentView.swift文件。

步骤2 为选中的地标设置对应的属性selectedLandmark,并用@State属性标识为状态属性。使用可选类型定义selectedLandmark,可以不用为它设置默认值。因此,无论是预览视图还是应用初始化时,都可以不需要用户选中地标进行渲染。

步骤3 把用户数据作为环境对象注入。ContentView本身不会直接依赖用户数据,但它的子视图需要访问用户数据。对于预览视图来说,为了正常预览和编译成功,ContentView需要获取用户数据。

section 10 step3

步骤4 在AppDelegate.swift中,为ContentView注入环境对象,这样可以让它的子视图访问到用户数据,应用也可以编译成功。

section 10 step4

步骤5 在ContentView中添加NavigationView作为顶级视图,并设置一个最小尺寸。

section 10 step5

步骤6 添加主视图,展示选中的地标。当用户选中地标列表中的某个地标时,被选中的地标数据就会被赋值到selectedLandmark属性上。

section 10 step6

步骤7 添加详情视图,详情视图不接收可选地标数据, 因些传入详情视图的地标数据需要确保不为空。用户选中地标前,地标详情视图不会渲染,这就是为会预览视图没有任何改变,还是和之前一样。

section 10 step7

步骤8 构建并运行应用。尝试改变过滤器的设置,或者点击详情页中的收藏按钮,观察视图内容的变化。

section 10 step8


0 个评论

要回复文章请先登录注册