3

So I'm using Mapbox, and I don't want to use the userTrackingMode = .followWithHeading as this causes way too much lag on my device as you rotate it. Instead, I'd like to maybe incorporate the .rotationEffect(Angle(degrees: degree)) SwiftUI property. My map is pretty much the basic map found here (https://docs.mapbox.com/help/tutorials/ios-swiftui/). My map is initialized in the following way:

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.

Any help in understanding how to rotate the view in this manner properly would be much appreciated.

nickcoding2
  • 142
  • 1
  • 8
  • 34

1 Answers1

2

The problem with your code is you rotate the view, which contains the map. The view is initially rectangular and the rotations are applied to this rectangle.

You can achieve this map rotation behavior with a MKMapView instance, but you have to do some additional work to use this class in SwiftUI. I have created a Playground showing how this can be achieved with a MKMapView. For different angles, change the heading of the MKMapCamera like

//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)

This is the playground code

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())

These are the results I got for heading = 0 and heading = 30. Hope this helps you. enter image description here

SamB
  • 1,560
  • 1
  • 13
  • 19
  • Unfortunately this solution also causes too much lag. It seems like the UIView animation provides much smoother animation most of the time, as I've tried both your solution (using built in map-rotation methods) and physical view rotation (using rotationEffect), but the first causes too much lag and the second, as you said the rotations applied to the actual view causes strange behavior... – nickcoding2 Aug 22 '21 at 14:32
  • Oh, that is too bad. I have had experience in applying rotations/scaling etc to views in the past, so in this case almost certain that applying rotations to the view is not the way forward. Eventhough this is not related to maps, I had noticed that generally animations could add a lag. Have you tried switching off animations from the map? You could try adding mapView.layer.removeAllAnimations() in makeUIView method. – SamB Aug 22 '21 at 16:13
  • I could remove the annotations, which does help with the lag, but it also makes it ugly, you know? No one likes a rotating map that clicks into place instead of being a smooth transition on rotation – nickcoding2 Aug 22 '21 at 19:02
  • animations* not annotations – nickcoding2 Aug 22 '21 at 19:43