ios - MKMapView userTrackingMode 在 SwiftUI 中重置

标签 ios swiftui mapkit mkusertrackingmode

我无法显示 MKMapView在 SwiftUI 中使用 userTrackingMode设置为 .follow .我正在展示一张 map :

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

而在这个MapView我是 (a) 设置 userTrackingMode (b) 确保我拥有使用时权限。我一直在基于 Storyboard的项目中使用这种模式。无论如何,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)
    }
}

这里一切看起来都不错,但 map (在模拟器和物理设备上)实际上并未处于跟随用户跟踪模式。

所以,我在上面进行了扩展,添加了一个采用 MKMapViewDelegate 的协调器。协议(protocol),所以我可以看到跟踪模式发生了什么:
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.follow
updateUIView(_:context:) MKUserTrackingMode.follow
mapView(_:didChange:animated:) MKUserTrackingMode.none

There’s something going on that is resetting the userTrackingMode to .none.

For giggles and grins, I tried resetting userTrackingMode, and that is no better:

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"
        }
    }
}

最佳答案

令人愤怒的是,在花费大量时间调试、准备问题等之后,看起来这种奇怪的行为只有在你不提供 frame 时才会出现。初始化期间:

let mapView = MKMapView()

当我使用以下内容时(即使最终 map 不是这个大小),它也可以正常工作:
let mapView = MKMapView(frame: UIScreen.main.bounds)

我仍然会发布这个,希望它能把其他人从这场噩梦中拯救出来。

关于ios - MKMapView userTrackingMode 在 SwiftUI 中重置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61262404/

相关文章:

ios - 亚马逊 Cognito 与 SwiftUI

swift - 如何在 SwiftUI 中设置图像的宽度和高度?

ios - MKMarkerAnnotationView 不显示标注

ios - 从解析中检索到的数据顺序

ios - 值未正确设置为用户对象

ios - Swift 如何在 Webview 中打开链接?

SwiftUI 2.0 : export images with . 文件导出器修饰符

ios - 一个应用程序中的多个 mapView

swift - “MKMapItem”无法转换为 'CLPlacemark'

ios - 如何创建一个包含 key ==> Value 的 .Plist?