MKMapView userTrackingMode 在 SwiftUI 中重置
MKMapView userTrackingMode reset in SwiftUI
我在 userTrackingMode
设置为 .follow
的 SwiftUI 中显示 MKMapView
时遇到问题。我正在显示一张地图:
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.follow
updateUIView(_:context:) MKUserTrackingMode.follow
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"
}
}
}
令人恼火的是,在花费大量时间调试、准备问题等之后,如果您在初始化期间不提供 frame
,这种奇怪的行为似乎只会出现:
let mapView = MKMapView()
当我使用以下内容时(即使最终地图不是这个大小),它也能正常工作:
let mapView = MKMapView(frame: UIScreen.main.bounds)
我仍然post希望它能将其他人从这场噩梦中拯救出来。
我在 userTrackingMode
设置为 .follow
的 SwiftUI 中显示 MKMapView
时遇到问题。我正在显示一张地图:
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.follow updateUIView(_:context:) MKUserTrackingMode.follow 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"
}
}
}
令人恼火的是,在花费大量时间调试、准备问题等之后,如果您在初始化期间不提供 frame
,这种奇怪的行为似乎只会出现:
let mapView = MKMapView()
当我使用以下内容时(即使最终地图不是这个大小),它也能正常工作:
let mapView = MKMapView(frame: UIScreen.main.bounds)
我仍然post希望它能将其他人从这场噩梦中拯救出来。