在SwiftUI中重置MKMapView userTrackingMode

问题描述 投票:0回答:1

[在将MKMapView设置为userTrackingMode的SwiftUI中显示.follow时遇到麻烦。我正在显示带有:

的地图
struct ContentView: View {
    var body: some View {
        MapView()
    }
}

并且在此MapView中,我(a)设置userTrackingMode,并且(b)确保我拥有使用时权限。我一直在基于情节提要的项目中执行这种模式。无论如何,MapView现在看起来像:

final class MapView: UIViewRepresentable {
    private lazy var locationManager = CLLocationManager()

    func makeUIView(context: Context) -> MKMapView {
        if CLLocationManager.authorizationStatus() == .notDetermined {
            locationManager.requestWhenInUseAuthorization()
        }

        let mapView = MKMapView()
        mapView.showsUserLocation = true
        mapView.userTrackingMode = .follow  // no better is mapView.setUserTrackingMode(.follow, animated: true)
        return mapView
    }

    func updateUIView(_ uiView: UIViewType, context: Context) {
        print(#function, uiView.userTrackingMode)
    }
}

这里一切看起来不错,但是地图(在模拟器和物理设备上)实际上都不处于关注用户跟踪模式。

所以,我在上面的内容上进行了扩展,添加了一个采用MKMapViewDelegate协议的协调器,因此我可以观察跟踪模式的情况:

final class MapView: UIViewRepresentable {
    private lazy var locationManager = CLLocationManager()

    func makeUIView(context: Context) -> MKMapView {
        if CLLocationManager.authorizationStatus() == .notDetermined {
            locationManager.requestWhenInUseAuthorization()
        }

        let mapView = MKMapView()
        mapView.delegate = context.coordinator
        mapView.showsUserLocation = true
        mapView.userTrackingMode = .follow  // no better is mapView.setUserTrackingMode(.follow, animated: true)
        return mapView
    }

    func updateUIView(_ uiView: UIViewType, context: Context) {
        print(#function, uiView.userTrackingMode)
    }

    func makeCoordinator() -> MapViewCoordinator {
        return MapViewCoordinator(self)
    }
}

class MapViewCoordinator: NSObject {
    var mapViewController: MapView

    var token: NSObjectProtocol?

    init(_ control: MapView) {
        self.mapViewController = control
    }
}

extension MapViewCoordinator: MKMapViewDelegate {
    func mapView(_ mapView: MKMapView, didChange mode: MKUserTrackingMode, animated: Bool) {
        print(#function, mode)
    }
}

结果是:

mapView(_:didChange:animated :) MKUserTrackingMode.followupdateUIView(_:context :) MKUserTrackingMode.followmapView(_:didChange:animated :) MKUserTrackingMode.none

正在发生某些事情,正在将userTrackingMode重置为.none

对于咯咯笑和笑容,我尝试重设userTrackingMode,这再好不过了:

func updateUIView(_ uiView: UIViewType, context: Context) {
    print(#function, uiView.userTrackingMode)
    uiView.userTrackingMode = .follow
}

不过这种杂乱无章的模式确实有效:

func updateUIView(_ uiView: UIViewType, context: Context) {
    print(#function, uiView.userTrackingMode)
    DispatchQueue.main.async {
        uiView.userTrackingMode = .follow
    }
}

或者在此初始过程之后,稍后重置userTrackingMode的任何事情也似乎起作用。

UIViewRepresentable我做错什么了吗? MKMapView中的错误?


这不是很相关,但这是我显示跟踪模式的例程:

extension MKUserTrackingMode: CustomStringConvertible {
    public var description: String {
        switch self {
        case .none:              return "MKUserTrackingMode.none"
        case .follow:            return "MKUserTrackingMode.follow"
        case .followWithHeading: return "MKUserTrackingMode.followWithHeading"
        @unknown default:        return "MKUserTrackingMode unknown/default"
        }
    }
}
ios swiftui mapkit mkusertrackingmode
1个回答
0
投票

令人发指的是,在花费大量时间进行调试,准​​备问题等等之后,只有在初始化期间不提供frame的情况下,这种奇怪的行为才会显现出来:

let mapView = MKMapView()

当我使用以下内容时(即使最终地图不是这个尺寸),它也可以正常工作:

let mapView = MKMapView(frame: UIScreen.main.bounds)

我仍会发布此邮件,希望它可以使其他人免于这场噩梦。

© www.soinside.com 2019 - 2024. All rights reserved.