【问题标题】:State restoration of MKMapView zooms out slightlyMKMapView 的状态恢复略微缩小
【发布时间】:2019-04-16 18:19:27
【问题描述】:

当恢复 mapView 的状态时,它会从保存期间的位置略微缩小。我创建了一个 iOS 单视图应用程序,其中仅包含一个填充整个视图的 MKMapView 来尝试解决此问题。我的调试打印语句显示地图值正在正确保存和恢复,但跨度纬度或经度最终会发生变化。我错过了什么?

编辑:

本题与以下题目相同:
MKMapView setRegion "snaps" to predefined zoom levels?
MKMapView show incorrectly saved region

作为一个实验,我添加了一个 MKCoordinateRegion 类型的类变量,并将 decodeRestorableState 方法中读取的区域分配给它。我还向视图控制器添加了一个按钮和操作处理程序,将 mapView 的区域设置为添加的变量的值。当点击按钮时,地图会放大到恢复预期的位置。奇怪的是,位置坐标在 decodeRestorableState 方法中工作不正确,但这些相同的坐标在按钮的操作处理程序中工作正常。

import UIKit
import MapKit

class ViewController: UIViewController {
    @IBOutlet weak var mapView: MKMapView!
}

extension MKMapView {
    override open func encodeRestorableState(with coder: NSCoder) {
        super.encodeRestorableState(with: coder)
        region.encodeRestorableState(with: coder)
        camera.encodeRestorableState(with: coder)
    }

    override open func decodeRestorableState(with coder: NSCoder) {
        super.decodeRestorableState(with: coder)
        region.decodeRestorableState(with: coder)
        camera.decodeRestorableState(with: coder)
    }
}

extension MKCoordinateRegion {
    private static let KEY_LATITUDE  = "Region.latitude"
    private static let KEY_LONGITUDE = "Region.longitude"
    private static let KEY_WIDTH     = "Region.spanWidth"
    private static let KEY_HEIGHT    = "Region.spanHeight"

    func encodeRestorableState(with coder: NSCoder) {
        coder.encode(center.latitude, forKey: MKCoordinateRegion.KEY_LATITUDE)
        coder.encode(center.longitude, forKey: MKCoordinateRegion.KEY_LONGITUDE)
        coder.encode(span.latitudeDelta, forKey: MKCoordinateRegion.KEY_HEIGHT)
        coder.encode(span.longitudeDelta, forKey: MKCoordinateRegion.KEY_WIDTH)
    }

    mutating func decodeRestorableState(with coder: NSCoder) {
        center.latitude = coder.decodeDouble(forKey: MKCoordinateRegion.KEY_LATITUDE)
        center.longitude = coder.decodeDouble(forKey: MKCoordinateRegion.KEY_LONGITUDE)
        span.latitudeDelta = coder.decodeDouble(forKey: MKCoordinateRegion.KEY_HEIGHT)
        span.longitudeDelta = coder.decodeDouble(forKey: MKCoordinateRegion.KEY_WIDTH)
    }
}

extension MKMapCamera {
    private static let KEY_ALTITUDE  = "Camera.altitude"
    private static let KEY_HEADING   = "Camera.heading"
    private static let KEY_PITCH     = "Camera.pitch"
    private static let KEY_LATITUDE  = "Camera.latitude"
    private static let KEY_LONGITUDE = "Camera.longitude"

    func encodeRestorableState(with coder: NSCoder) {
        coder.encode(altitude, forKey: MKMapCamera.KEY_ALTITUDE)
        coder.encode(heading, forKey: MKMapCamera.KEY_HEADING)
        coder.encode(Double(pitch), forKey: MKMapCamera.KEY_PITCH)
        coder.encode(centerCoordinate.latitude, forKey: MKMapCamera.KEY_LATITUDE)
        coder.encode(centerCoordinate.longitude, forKey: MKMapCamera.KEY_LONGITUDE)
    }

    func decodeRestorableState(with coder: NSCoder) {
        altitude = coder.decodeDouble(forKey: MKMapCamera.KEY_ALTITUDE)
        heading = coder.decodeDouble(forKey: MKMapCamera.KEY_HEADING)
        pitch = CGFloat(coder.decodeDouble(forKey: MKMapCamera.KEY_PITCH))
        centerCoordinate.latitude = coder.decodeDouble(forKey: MKMapCamera.KEY_LATITUDE)
        centerCoordinate.longitude = coder.decodeDouble(forKey: MKMapCamera.KEY_LONGITUDE)
    }
}

【问题讨论】:

    标签: ios swift mkmapview zooming region


    【解决方案1】:

    有同样的问题。我的解决方法是在我的视图控制器的 viewDidAppear 中设置 mapView.camera。

    let mapCameraKey = "MapCameraKey"
    var restoredCamera: MKMapCamera?
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
    
        if let restoredCamera = restoredCamera {
            mapView.camera = restoredCamera
        }
    }
    
    override func encodeRestorableState(with coder: NSCoder) {
        super.encodeRestorableState(with: coder)
    
        coder.encode(mapView.camera, forKey: mapCameraKey)
    }
    
    override func decodeRestorableState(with coder: NSCoder) {
        super.decodeRestorableState(with: coder)
    
        restoredCamera = coder.decodeObject(forKey: mapCameraKey) as? MKMapCamera
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-10-14
      • 2014-01-28
      • 1970-01-01
      • 2012-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多