使用NSUserDefaults保存MKMapView的区域

时间:2016-08-29 20:47:27

标签: ios swift mapkit nsuserdefaults

每当我的地图视图区域发生变化时,我都会将中心和范围值保存到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次加载时生成了字典,而根本没有改变地图区域:

["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]

长值被正确保存,但其他3个表现得很奇怪。

4 个答案:

答案 0 :(得分:1)

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

这是region结构的扩展,使您可以从多个位置编写它:

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)
  }
}

使用上述扩展名,只需在包含地图视图的视图控制器中使用以下代码即可:

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不再需要synchronize

答案 1 :(得分:0)

您可以直接保存NSDictionary数据,如下所示。

让locationData = [" lat":0.22222,                             " LNG":0.33333,                             " D_lat":0.0001,                             " D_lng":0.0001]         NSUserDefaults.standardUserDefaults()。setObject(locationData,forKey:" location")         NSUserDefaults.standardUserDefaults()。同步()

否则你可以得到如下的NSDicationary数据。

let savedLocation = NSUserDefaults.standardUserDefaults()。dictionaryForKey(" location")

let savedLocation = NSUserDefaults.standardUserDefaults()。dataForKey(" location")为?的NSDictionary

答案 2 :(得分:0)

您最好使用

NSUserDefaults.standardUserDefaults()。setDouble(locationData,forKey:" locationData")& NSUserDefaults.standardUserDefaults()。synchronize()

保存位置数据时。

但请用户

NSUserDefaults.standardUserDefaults()doubleForKey(" locationData&#34)。

获取位置数据时。

答案 3 :(得分:0)

我意识到在regionDidChangeAnimated函数中保存区域中心和跨度时会出现问题。这导致不可预测的结果。保存的更好地方是viewWillDisappear函数:

Python 3.5.1 (v3.5.1:37a07cee5969, Dec  6 2015, 01:38:48) [MSC v.1900 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> 
===== RESTART: E:\scanned\als course\12 15 14 the al project\dev code\8 29 16 test plots.py =====
ranks shape (31,)
dates shape (31,)
ranks type <class 'numpy.ndarray'>
dates type <class 'numpy.ndarray'>
dates shape first dimension 31
['2016-01-01' '2016-01-02' '2016-01-03' '2016-01-04' '2016-01-05'
 '2016-01-06' '2016-01-07' '2016-01-08' '2016-01-09' '2016-01-10'
 '2016-01-11' '2016-01-12' '2016-01-13' '2016-01-14' '2016-01-15'
 '2016-01-16' '2016-01-17' '2016-01-18' '2016-01-19' '2016-01-20'
 '2016-01-21' '2016-01-22' '2016-01-23' '2016-01-24' '2016-01-25'
 '2016-01-26' '2016-01-27' '2016-01-28' '2016-01-29' '2016-01-30'
 '2016-01-31']
[ 50.  50.  50.  50.  50.  50.  50.  50.  50.  50.  50.  50.  50.  50.  50.
  50.  50.  50.  50.  50.  50.  50.  50.  50.  50.  50.  50.  50.  50.  50.
  50.]
Traceback (most recent call last):
  File "E:\scanned\als course\12 15 14 the al project\dev code\8 29 16 test plots.py", line 23, in <module>
    plt.plot_date(dates,2)
  File "C:\Users\dave\AppData\Local\Programs\Python\Python35-32\lib\site-packages\matplotlib\pyplot.py", line 3173, in plot_date
    data=data, **kwargs)
  File "C:\Users\dave\AppData\Local\Programs\Python\Python35-32\lib\site-packages\matplotlib\__init__.py", line 1812, in inner
    return func(ax, *args, **kwargs)
  File "C:\Users\dave\AppData\Local\Programs\Python\Python35-32\lib\site-packages\matplotlib\axes\_axes.py", line 1494, in plot_date
    ret = self.plot(x, y, fmt, **kwargs)
  File "C:\Users\dave\AppData\Local\Programs\Python\Python35-32\lib\site-packages\matplotlib\__init__.py", line 1812, in inner
    return func(ax, *args, **kwargs)
  File "C:\Users\dave\AppData\Local\Programs\Python\Python35-32\lib\site-packages\matplotlib\axes\_axes.py", line 1424, in plot
    for line in self._get_lines(*args, **kwargs):
  File "C:\Users\dave\AppData\Local\Programs\Python\Python35-32\lib\site-packages\matplotlib\axes\_base.py", line 386, in _grab_next_args
    for seg in self._plot_args(remaining, kwargs):
  File "C:\Users\dave\AppData\Local\Programs\Python\Python35-32\lib\site-packages\matplotlib\axes\_base.py", line 364, in _plot_args
    x, y = self._xy_from_xy(x, y)
  File "C:\Users\dave\AppData\Local\Programs\Python\Python35-32\lib\site-packages\matplotlib\axes\_base.py", line 223, in _xy_from_xy
    raise ValueError("x and y must have same first dimension")
ValueError: x and y must have same first dimension
>>>