SwiftUI-地图框架

Apple 提供了一个 SwiftUI Map视图,它精美地包装了底层地图框架,让我们可以将地图、注释等与 SwiftUI 视图层次结构的其余部分一起放置。 地图及其所有配置数据都来自一个名为 MapKit 的专用框架,

简单显示地图

可以调整用户使用地图的方式,例如他们是否可以缩放或旋转其位置。例如,我们可以制作一张始终保持以特定位置为中心的地图,但用户仍然可以调整旋转和缩放:

scss 复制代码
Map(interactionModes: [.rotate, .zoom])  

可以不指定交互模式,这意味着地图始终是完全固定的:

scss 复制代码
Map(interactionModes: [ ])  

使用mapStyle()修改器来控制地图的外观

  • 卫星地图
  • 将卫星地图和街道地图结合起来
  • 可以获取两张地图以及真实的海拔高度,创建 3D 地图

这些都是简单的自定义选项,但其中三个需要更多思考:控制位置、放置注释和处理点击。

初始位置

创建一个存储伦敦位置的常量属性,跨度指定为 1 度 x 1 度:

less 复制代码
let position = MapCameraPosition.region(

    MKCoordinateRegion(
        center: CLLocationCoordinate2D(latitude: 51.507222, longitude: -0.1275),
        span: MKCoordinateSpan(latitudeDelta: 1, longitudeDelta: 1)
    )
)  

初始化传入位置

scss 复制代码
Map(initialPosition: position)

移动位置

如果您想随着时间的推移更改位置,则需要将其标记为@State然后将其作为绑定传递。

当position值发生变化,地图位置就会运动到该位置

跟踪位置变化

onMapCameraChange()修饰符,可以告诉我们位置何时发生变化,是立即发生变化还是在运动结束后发生变化。 可以编写当他们完成拖动地图时获取更新

scss 复制代码
Map(position: $position)
    .onMapCameraChange { context in

        print(context.region)
    }  

也可以让它发布连续更新:

scss 复制代码
Map(position: $position)

    .onMapCameraChange(frequency: .continuous) { context in

        print(context.region)
    }  

放置注释球 Maker

需要三个步骤:定义包含您的位置的新数据类型,创建包含您所有位置的数组,然后将它们添加为地图中的注释。无论您创建什么新数据类型来存储位置,它都必须符合Identifiable协议,以便 SwiftUI 可以唯一地识别每个地图标记。

swift 复制代码
struct Location: Identifiable {

    let id = UUID()
    var name: String
    var coordinate: CLLocationCoordinate2D
}  
php 复制代码
let locations = [

    Location(name: "Buckingham Palace", coordinate: CLLocationCoordinate2D(latitude: 51.501, longitude: -0.141)),
    Location(name: "Tower of London", coordinate: CLLocationCoordinate2D(latitude: 51.508, longitude: -0.076))
] 

第三步是重要的部分:我们可以将该位置数组Map作为其内容输入到视图中。 SwiftUI 为我们提供了几种不同的内容类型,但一种简单的内容类型称为Marker:附有标题和纬度/经度坐标的气球。

scss 复制代码
Map {
    ForEach(locations) { location in
        Marker(location.name, coordinate: location.coordinate)
    }
}  

自定义标记

如果您想更好地控制标记在地图上的显示方式,请使用Annotation。这使您可以提供完全自定义的视图,来代替标准系统标记气球 Maker,并且如果您愿意,您可以隐藏默认标题,以便您可以将其替换为您自己的标题,如下所示:

scss 复制代码
Map {
    ForEach(locations) { location in
    
        Annotation(location.name, coordinate: location.coordinate) {

            Text(location.name)
                .font(.headline)
                .padding()
                .background(.blue)
                .foregroundStyle(.white)
                .clipShape(.capsule)
        }
        .annotationTitles(.hidden)  
    }
} 

点击地图

最后,您可以使用onTapGesture() 处理地图上的点击。这告诉我们用户在地图上点击的位置,但它是在屏幕坐标中进行的- 例如,距顶部 50 点,距左侧 100 点。

为了获得地图上的实际位置,我们需要一个名为 MapReader 的特殊视图。当您将其中一个包裹在地图上时,您将收到一个特殊的MapProxy对象,该对象能够将屏幕位置转换为地图位置,并以另一种方式转换回来。

scss 复制代码
MapReader { proxy in

    Map()
        .onTapGesture { position in
        
            if let coordinate = proxy.convert(position, from: .local) {
                print(coordinate)
            }
        }
}  

.local部分意味着我们正在转换地图本地坐标空间中的位置,这意味着我们正在使用的点击位置是相对于地图的左上角而不是整个屏幕或其他一些坐标空间。

相关推荐
crasowas20 小时前
iOS - 超好用的隐私清单修复脚本(持续更新)
ios·app store
ii_best1 天前
ios按键精灵脚本开发:ios悬浮窗命令
ios
Code&Ocean1 天前
iOS从Matter的设备认证证书中获取VID和PID
ios·matter·chip
/**书香门第*/1 天前
Laya ios接入goole广告,开始接入 2
ios
恋猫de小郭2 天前
什么?Flutter 可能会被 SwiftUI/ArkUI 化?全新的 Flutter Roadmap
flutter·ios·swiftui
网安墨雨2 天前
iOS应用网络安全之HTTPS
web安全·ios·https
福大大架构师每日一题2 天前
37.1 prometheus管理接口源码讲解
ios·iphone·prometheus
BangRaJun3 天前
LNCollectionView-替换幂率流体
算法·ios·设计
刘小哈哈哈3 天前
iOS 多个输入框弹出键盘处理
macos·ios·cocoa
靴子学长3 天前
iOS + watchOS Tourism App(含源码可简单复现)
mysql·ios·swiftui