Сброс MKMapView userTrackingMode в SwiftUI
У меня проблемы с отображением MKMapView
в SwiftUI с userTrackingMode
установлен в .follow
. Я показываю карту с:
struct ContentView: View {
var body: some View {
MapView()
}
}
И в этом MapView
Я (а) установка userTrackingMode
и (б) убедиться, что у меня есть разрешения на использование. Я все время делаю такой шаблон в проектах на основе раскадровки. Во всяком случае,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. следовать updateUIView(_:context:) MKUserTrackingMode. следовать mapView(_: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"
}
}
}
1 ответ
К сожалению, после чрезмерного количества времени, потраченного на отладку этого, подготовку вопроса и т. Д., Похоже, что это странное поведение проявляется только в том случае, если вы не предоставляете frame
во время инициализации:
let mapView = MKMapView()
Когда я использовал следующее (даже несмотря на то, что окончательная карта не такого размера), все работало правильно:
let mapView = MKMapView(frame: UIScreen.main.bounds)
Я все еще отправлю это в надежде, что это спасет кого-то еще от этого кошмара.