[在将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"
}
}
}
令人发指的是,在花费大量时间进行调试,准备问题等等之后,只有在初始化期间不提供frame
的情况下,这种奇怪的行为才会显现出来:
let mapView = MKMapView()
当我使用以下内容时(即使最终地图不是这个尺寸),它也可以正常工作:
let mapView = MKMapView(frame: UIScreen.main.bounds)
我仍会发布此邮件,希望它可以使其他人免于这场噩梦。