SwiftUI:集成 MapKit

时间:2022-07-23
本文章向大家介绍SwiftUI:集成 MapKit,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

自从2007年第一台设备问世以来,地图就一直是iPhone的核心功能,开发者几乎已经可以使用底层框架了。它叫做 MapKit,和UIKit一样,如果我们不介意进行其他工作,我们可以在SwiftUI中使用它——是的,这确实意味着使用协调器。

让我们从简单的事情开始,然后逐步发展。新建一个名为“ MapView”的SwiftUI视图,然后在顶部添加 MapKit 的导入。这次我们不会使用 UIViewControllerRepresentable 协议,因为MapKit不使用视图控制器。

一种经典的软件构建方式称为“ MVC”,它将我们的代码分为三种类型:对象模型(我们的数据),视图(我们的布局)和控制器(连接模型和视图的胶水代码)。苹果在UIKit及其包括MapKit在内的其他框架中使用了MVC,但增加了一个有趣的变化:视图控制器。他们是视图,控制器,还是两者都没有?Apple并没有真正为我们回答这个问题,这就是为什么您会在iOS应用开发中看到数百种MVC的原因。

在教UIKit时,我首先向人们解释了视图是一种布局,例如一些文本,按钮或图像,而视图控制器是内容的一个屏幕。在学习UIKit知识时,您会发现实际上可以在一个屏幕上拥有许多视图控制器,但这是学习过程中有用的心理模型。

所有这些都很重要,因为当我们使用UIImagePickerController时,它被设计为可作为一个完整的信息屏幕使用——我们并未尝试为其添加功能,因为它被设计为可作为一个独立的单元使用。相比之下,MapKit为我们提供了MKMapView,正如您从名称中可以看出的,这是一个视图而不是一个控制器,这意味着它仅显示我们提供给它的内容。

这就是为什么在使用 MapKit 时不使用UIViewControllerRepresentable的原因:MKMapView使用视图,因此我们需要使用UIViewRepresentable。有用的工作原理几乎相同:我们需要编写称为makeUIView()updateUIView()的方法,这些方法用于实例化地图视图并在SwiftUI状态更改时对其进行更新。但是,对于视图而言,此更新方法比视图控制器更为重要,因为SwiftUI代码与UIView对象之间存在更多的通信——尽管我们将该方法留给视图控制器使用,但您将在视图中使用大量此方法。

我们将很快恢复更新,但现在我们将使用另一种空方法。至于 make 方法,这将创建一个新的MKMapView并将其返回回——我们将很快添加更多内容。

将此替换为当前的MapView结构:

struct MapView: UIViewRepresentable {
    func makeUIView(context: UIViewRepresentableContext<MapView>) -> MKMapView {
        let mapView = MKMapView()
        return mapView
    }

    func updateUIView(_ view: MKMapView, context: UIViewRepresentableContext<MapView>) {
    }
}

在继续之前,我想向您展示一些Swift魔术。回到项目13在SwiftUI视图中包装UIViewController,当我向您介绍UIViewControllerRepresentable协议时,我们只是短暂地使用了typealias。这是Swift的一种让我们为现有类型创建新名称的方法,通常这样做是为了使它们更容易记住。

好吧,UIViewControllerRepresentable和UIViewRepresentable都包含内置的类型别名。如果右键单击UIViewRepresentable,然后选择“Jump To Definition”,则会看到SwiftUI生成的界面,它还将在UIViewRepresentable协议中向您显示此行:

typealias Context = UIViewRepresentableContext<Self>

这将创建一个新的类型别名-类型名称-称为“上下文 Context”,无论Swift在代码中看到的Context在哪个位置,它将认为它与UIViewRepresentableContext <Self>相同,其中Self是我们正在使用的任何类型。实际上,这意味着我们只能编写Context而不是UIViewRepresentableContext <MapView>,它们的含义完全相同。

无论如何,我们已经构建了地图视图的第一个版本,因此我们可以继续使用它。返回 ContentView.swift 并用以下内容替换文本视图:

MapView()
    .edgesIgnoringSafeArea(.all)

Xcode目前无法很好地预览地图视图,因此建议您在模拟器中运行该应用以查看其外观。您应该会发现可以点击并拖动地图,但是如果按住Option键,您会看到第二根虚拟手指出现,因此您可以自由捏合和旋转。仅几行代码效果就挺好了!

当然,您真正想做的就是通过一些地标使地图栩栩如生,因此我们接下来将解决该问题……