ios - 使用 NSMutableArray 保存和加载 MapAnnotation 引脚

标签 ios nsmutablearray mkmapview nsuserdefaults mkannotation

我需要有关 MapAnnotation 代码的帮助。我想保存 map 图钉,以便用户可以返回 map 并查看他/她放置的图钉。

但是,此代码在 View 加载时不显示引脚。

添加和保存图钉的代码:

- (void)addPinToMap:(UIGestureRecognizer *)gestureRecognizer
{

if (gestureRecognizer.state != UIGestureRecognizerStateBegan)
    return;



CGPoint touchPoint = [gestureRecognizer locationInView:self.mapView];
CLLocationCoordinate2D touchMapCoordinate =
[self.mapView convertPoint:touchPoint toCoordinateFromView:self.mapView];

 //NSMutableArray *pincoords = (NSMutableArray *)[[NSUserDefaults standardUserDefaults] objectForKey:@"saveCoords"];

NSMutableDictionary *pindict;

NSUserDefaults *def = [NSUserDefaults standardUserDefaults];

NSMutableArray *pincoords = [def objectForKey:@"saveCoords"];


CLLocationCoordinate2D coordinates;

coordinates.latitude = touchMapCoordinate.latitude;
coordinates.longitude = touchMapCoordinate.longitude;

NSNumber* latDegrees = [NSNumber numberWithFloat:touchMapCoordinate.latitude];
NSNumber* longDegrees = [NSNumber numberWithFloat:touchMapCoordinate.longitude];



 [pindict setObject:latDegrees forKey:@"pinlat"];
  [pindict setObject:longDegrees forKey:@"pinlong"];








 MapAnnotation *toAdd = [[MapAnnotation alloc]init];


toAdd.coordinate = coordinates;
toAdd.title = @"Svampe Spot";

[self.mapView addAnnotation:toAdd];


[pincoords addObject:pindict];

[def synchronize];


}

我的加载代码:

- (void)viewDidLoad
{

 [super viewDidLoad];


   NSUserDefaults *def = [NSUserDefaults standardUserDefaults];

   NSMutableArray *pincoords = [def objectForKey:@"saveCoords"];

   for (NSDictionary *pindict in pincoords) {

     CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake([[pindict objectForKey:@"pinlat"] floatValue], [[pindict objectForKey:@"pinlong"] floatValue]);

    MapAnnotation *mapPin = [[MapAnnotation alloc]init];





    mapPin.coordinate = coordinate;
    mapPin.title = @"Svampe Spot";

    [self.mapView addAnnotation:mapPin];
    [def synchronize];


    [def synchronize];

 }

}

将不胜感激!!

删除特定注释的代码:

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)mapViewpin
calloutAccessoryControlTapped:(UIControl *)control {


NSUserDefaults *def = [NSUserDefaults standardUserDefaults];

NSMutableArray *pincoords = [def objectForKey:@"saveCoords"];

for (NSDictionary *pindict in pincoords) {

 CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(
                                                               [[pindict objectForKey:@"pinlat"] doubleValue],
                                                               [[pindict objectForKey:@"pinlong"] doubleValue]);

 MapAnnotation *mapPin = mapViewpin.annotation;

 mapPin.coordinate =coordinate;

 [self.mapView removeAnnotation:mapPin];
 [def removeObjectForKey:@"saveCoords"];

 [def synchronize];
}


}

这会将它们全部删除。我如何使其特定于点击了按钮的注释?

最佳答案

Volker 的回答确实指出了一个重要问题:

用户第一次添加 pin 时,用户默认值中将没有已保存的数组,因此 pinCoords 将为 nil。因此,对数组的 addObject 调用不会执行任何操作。如果它是 nil,您需要通过分配一个空数组来处理这种情况,以便您可以向其中添加对象。


但是,addPinToMap: 中仍然存在其他问题,即使在修复上述问题后代码仍无法正常工作:

  1. pindict 变量已声明,但从未分配。当您对其调用 setObject:forKey: 时,这将导致崩溃或什么都不做。您需要分配 pindict 变量。
  2. 使用NSUserDefaultsobjectForKey: 将返回一个不可变 对象。这意味着即使 pincoords 被声明为 NSMutableArrayobjectForKey: 也会返回一个 NSArray(如果它找到一个用户默认值中键的值)。因此,addObject 调用将再次失败(这次是崩溃),因为您无法将对象添加到 NSArray。您需要做的是获取 objectForKey: 的结果,并通过调用 mutableCopy 制作它的可变版本。
  3. 将新坐标添加到 pinCoords 后,代码不会将更新后的数组保存回用户默认值。它只是调用同步。在调用 synchronize 之前,您需要通过调用 setObject:forKey: 将数组实际保存为用户默认值。

进行上述所有更改后,代码应该可以工作了。


我还建议再进行两处更改以改进代码(尽管这些不会阻止它正常工作):

  1. 不要将坐标保存为float 值,而是将它们保存为double。 Core Location中的纬度和经度实际上是double类型(CLLocationDegrees实际上是double)。您还将获得更好的精度。所以在 addPinToMap: 中,使用 numberWithDouble 而不是 numberWithFloat 并且在 viewDidLoad 中,使用 doubleValue 而不是 floatValue
  2. viewDidLoad 中,在 for 循环内,您调用了两次 synchronize。这些调用毫无意义——删除它们。


addPinToMap: 中的最终更新代码如下:

- (void)addPinToMap:(UIGestureRecognizer *)gestureRecognizer
{
    if (gestureRecognizer.state != UIGestureRecognizerStateBegan)
        return;

    CGPoint touchPoint = [gestureRecognizer locationInView:self.mapView];
    CLLocationCoordinate2D touchMapCoordinate = [self.mapView convertPoint:touchPoint toCoordinateFromView:self.mapView];

    NSMutableDictionary *pindict = [NSMutableDictionary dictionary];

    NSUserDefaults *def = [NSUserDefaults standardUserDefaults];

    NSMutableArray *pincoords = [[def objectForKey:@"saveCoords"] mutableCopy];
    if (pincoords == nil)
    {
        pincoords = [NSMutableArray array];
    }

    CLLocationCoordinate2D coordinates;

    coordinates.latitude = touchMapCoordinate.latitude;
    coordinates.longitude = touchMapCoordinate.longitude;

    NSNumber* latDegrees = [NSNumber numberWithDouble:touchMapCoordinate.latitude];
    NSNumber* longDegrees = [NSNumber numberWithDouble:touchMapCoordinate.longitude];

    [pindict setObject:latDegrees forKey:@"pinlat"];
    [pindict setObject:longDegrees forKey:@"pinlong"];

    MapAnnotation *toAdd = [[MapAnnotation alloc]init];

    toAdd.coordinate = coordinates;
    toAdd.title = @"Svampe Spot";

    [self.mapView addAnnotation:toAdd];

    [pincoords addObject:pindict];

    [def setObject:pincoords forKey:@"saveCoords"];

    [def synchronize];
}

viewDidLoad 中更新的 for 循环将是这样的:

for (NSDictionary *pindict in pincoords) {

    CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(
        [[pindict objectForKey:@"pinlat"] doubleValue], 
        [[pindict objectForKey:@"pinlong"] doubleValue]);

    MapAnnotation *mapPin = [[MapAnnotation alloc]init];

    mapPin.coordinate = coordinate;
    mapPin.title = @"Svampe Spot";

    [self.map addAnnotation:mapPin];
}

关于ios - 使用 NSMutableArray 保存和加载 MapAnnotation 引脚,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21468053/

相关文章:

objective-c - 理解数组指针

ios - 比较并从NSMutableArray获取索引

iphone - OS 4 上的平滑注释移动

iphone - 滑动删除 UITableView

iphone - 如何将 exif 元数据写入图像(不是相机胶卷,只是 UIImage 或 JPEG)

ios - 在 iOS 7 中呈现和关闭模态视图

ios - 将图钉放在当前位置

ios - 获取 rightBarButtonItem 的字体大小

iphone - iOS 初学者 : NSMutableArray + int variable for storing array index position (Where is the connection)

ios - 在 MKMapView 上绘制 CLLocation/CLLocationCoordinate2D