ios - 使用 NSUserDefaults 保存 MKMapView 的 Region

标签 ios swift mapkit nsuserdefaults

每当我的 map View 区域发生变化时,我都会将中心和跨度值保存到 NSUserDefaults 中,这样当应用程序再次打开时,它将位于同一位置。

func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
    let defaults = NSUserDefaults.standardUserDefaults()
    defaults.setValue(myMapView.centerCoordinate.latitude, forKey: "lat")
    defaults.setValue(myMapView.centerCoordinate.longitude, forKey: "long")
    defaults.setValue(myMapView.region.span.latitudeDelta, forKey: "latDelta")
    defaults.setValue(myMapView.region.span.longitudeDelta, forKey: "longDelta")
}

这是我的 viewDidLoad 中默认设置的位置:

override func viewDidLoad() {
    super.viewDidLoad()

    let defaults = NSUserDefaults.standardUserDefaults()
    if  let lat = defaults.valueForKey("lat"),
        let long = defaults.valueForKey("long"),
        let latDelta = defaults.valueForKey("latDelta"),
        let longDelta = defaults.valueForKey("longDelta")

    {
        let center: CLLocationCoordinate2D = CLLocationCoordinate2DMake(lat as! Double, long as! Double)
        let span: MKCoordinateSpan = MKCoordinateSpanMake(latDelta as! Double, longDelta as! Double)
        let region: MKCoordinateRegion = MKCoordinateRegionMake(center, span)
        myMapView.setRegion(region, animated: true)
    }
}

但是,当我再次打开应用程序时,该区域不会像应用程序关闭时那样显示。每次我关闭并重新打开时,未正确保存的值似乎都会增加一个恒定值。这是怎么回事?

我改用dictionaryForKey方法,这是连续加载3次后得到的字典,根本不改变 map 区域:

["long": -95.78, "latDelta": 76.06, "lat": 37.13, "longDelta": 61.27]
["long": -95.78, "latDelta": 88.18, "lat": 31.93, "longDelta": 76.82]
["long": -95.78, "latDelta": 100.69, "lat": 25.71, "longDelta": 86.56]

long 值已正确保存,但其他 3 个值的行为异常。

最佳答案

另一个 Swift 选项(在 Swift 5 中),将代码抽象为区域结构的扩展。

这是区域结构的扩展,允许您从多个位置写入它:

extension MKCoordinateRegion {
  public func write(toDefaults defaults:UserDefaults, withKey key:String) {
    let locationData = [center.latitude, center.longitude,
                        span.latitudeDelta, span.longitudeDelta]
    defaults.set(locationData, forKey: key)
  }

  public static func load(fromDefaults defaults:UserDefaults, withKey key:String) -> MKCoordinateRegion? {
    guard let region = defaults.object(forKey: key) as? [Double] else { return nil }
    let center = CLLocationCoordinate2D(latitude: region[0], longitude: region[1])
    let span = MKCoordinateSpan(latitudeDelta: region[2], longitudeDelta: region[3])
    return MKCoordinateRegion(center: center, span: span)
  }
}

使用上述扩展只需要在包含 map View 的 View Controller 中添加以下代码:

private let kMapRegion = "region"

override func viewWillAppear(_ animated: Bool) {
  if let region = MKCoordinateRegion.load(fromDefaults: UserDefaults.standard, withKey: kMapRegion) {
    mapView.region = region
  }
}

override func viewWillDisappear(_ animated: Bool) {
  mapView.region.write(toDefaults: UserDefaults.standard, withKey: kMapRegion)
}

(iOS 12之后的UserDefaults不再需要同步)

关于ios - 使用 NSUserDefaults 保存 MKMapView 的 Region,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39214923/

相关文章:

ios - 如何在以逗号分隔的 NSMutableString 中添加多个字符串

ios - 如何在iPhone真机上打开数据库sqlite文件?

ios - 向内部内容大小添加填充在 UILabel 中不起作用

ios - 禁用 UIPickerView 中的特定行值

ios - (Swift) 在我的位置 MapKit 内设置一个 1 公里的半径

ios - 在 MKMapView 中标记位置

ios - cordova cli 命令在 ios 上失败 : ENOENT cordova-config. json.SOME_NUMBER

swift - SKSpriteNode 动画自下而上显示

ios - 使用 MKMapKit 显示用户位置( Objective-C )

android - Flutter multi_image_picker相机选项未在iOS中显示。当我已经启用摄像头并将权限写入info.plist中时