首页 > 解决方案 > 如何使用 SwiftUI 对地图应用动态旋转

问题描述

所以我正在使用 Mapbox,我不想使用 userTrackingMode = .followWithHeading,因为当你旋转它时,这会导致我的设备出现太多延迟。相反,我想加入 .rotationEffect(Angle(degrees: degree)) SwiftUI 属性。我的地图几乎就是在这里找到的基本地图(https://docs.mapbox.com/help/tutorials/ios-swiftui/)。我的地图通过以下方式初始化:

Map()
    .edgesIgnoringSafeArea(.all)
    //Here I tried to add a rotation effect, where the degree is the user heading, but this causes a weird graphical glitch because of the ignoring safe area property.

任何有助于理解如何以这种方式正确旋转视图的帮助将不胜感激。

标签: swiftswiftuirotationmapboxsafearea

解决方案


您的代码的问题是您旋转了包含地图的视图。视图最初是矩形的,并且旋转应用于此矩形。

您可以使用实例来实现这种地图旋转行为MKMapView,但您必须做一些额外的工作才能在 SwiftUI 中使用此类。我创建了一个Playground展示如何使用MKMapView. 对于不同的角度,改变类似headingMKMapCamera

//for 0 degrees angle
@State private var camera = MKMapCamera(lookingAtCenter: CLLocationCoordinate2D(latitude: 37.334_900, longitude: -122.009_020), fromDistance: 7500, pitch: 0, heading: 0)

//for 30 degrees angle
@State private var camera = MKMapCamera(lookingAtCenter: CLLocationCoordinate2D(latitude: 37.334_900, longitude: -122.009_020), fromDistance: 7500, pitch: 0, heading: 30)

这是操场代码

import SwiftUI
import MapKit
import PlaygroundSupport

struct ContentView: View {

    //for 0 degrees angle, set heading = 0
    @State private var camera = MKMapCamera(lookingAtCenter: CLLocationCoordinate2D(latitude: 37.334_900, longitude: -122.009_020), fromDistance: 7500, pitch: 0, heading: 0)
    
    var body: some View {
        MapView(camera: $camera)
                .edgesIgnoringSafeArea(.all)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct MapView: UIViewRepresentable {
    @Binding var camera: MKMapCamera
    
    func makeUIView(context: Context) -> MKMapView {
        let mapView = MKMapView()
        mapView.delegate = context.coordinator
        mapView.setCamera(camera, animated: false)
        return mapView
    }

    func updateUIView(_ view: MKMapView, context: Context) {

    }

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    class Coordinator: NSObject, MKMapViewDelegate {
        var parent: MapView

        init(_ parent: MapView) {
            self.parent = parent
        }
    }
}

PlaygroundPage.current.setLiveView(ContentView())

这些是我得到的结果heading = 0heading = 30。希望这对您有所帮助。 在此处输入图像描述


推荐阅读