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

相关推荐
叽哥9 小时前
Flutter Riverpod上手指南
android·flutter·ios
用户091 天前
SwiftUI Charts 函数绘图完全指南
ios·swiftui·swift
YungFan1 天前
iOS26适配指南之UIColor
ios·swift
权咚2 天前
阿权的开发经验小集
git·ios·xcode
用户092 天前
TipKit与CloudKit同步完全指南
ios·swift
法的空间2 天前
Flutter JsonToDart 支持 JsonSchema
android·flutter·ios
2501_915918412 天前
iOS 上架全流程指南 iOS 应用发布步骤、App Store 上架流程、uni-app 打包上传 ipa 与审核实战经验分享
android·ios·小程序·uni-app·cocoa·iphone·webview
00后程序员张2 天前
iOS App 混淆与加固对比 源码混淆与ipa文件混淆的区别、iOS代码保护与应用安全场景最佳实践
android·安全·ios·小程序·uni-app·iphone·webview
Magnetic_h3 天前
【iOS】设计模式复习
笔记·学习·ios·设计模式·objective-c·cocoa
00后程序员张3 天前
详细解析苹果iOS应用上架到App Store的完整步骤与指南
android·ios·小程序·https·uni-app·iphone·webview