我需要MapAnnotation代码的帮助。我想保存地图别针,以便用户可以回到地图并查看他/她放置的地图。
但是,在加载视图时,此代码不会显示引脚。
添加和保存引脚的代码:
- (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];
}
}
这将删除所有内容。如何使其特定于按钮被点击的注释?
答案 0 :(得分:2)
Volker的回答确实指出了一个重要问题:
用户首次添加图钉时,用户默认设置中不会保存任何阵列,因此pinCoords
将为nil
。因此,对数组的addObject
调用将不执行任何操作。你需要通过分配一个空数组nil
来处理这种情况,这样你就可以向它添加对象了。
但是,addPinToMap:
中仍有其他问题会阻止代码在修复上述内容后仍然有效:
pindict
变量已声明但从未已分配。当您在其上调用setObject:forKey:
或什么都不做时,这会导致崩溃。您需要分配pindict
变量。NSUserDefaults
,objectForKey:
将返回不可变对象。这意味着即使pincoords
被声明为NSMutableArray
,objectForKey:
也会返回NSArray
(如果它在用户默认值中找到键的值)。因此,addObject
调用将再次失败(这次是崩溃),因为您无法将对象添加到NSArray
。您需要做的是获取objectForKey:
的结果并通过调用mutableCopy
制作一个可变版本。pinCoords
后,代码不会将更新后的数组保存回用户默认值。它只是调用synchronize
。在调用synchronize
之前,您需要通过调用setObject:forKey:
将数组实际保存为用户默认值。完成上述所有更改后,代码应该可以正常工作。
我还建议另外两个更改来改进代码(虽然这些不会阻止它工作):
float
值,而是将其保存为double
。核心位置的纬度和经度实际上是double
类型(CLLocationDegrees
实际上是双倍)。你也会获得更好的精确度。因此,在addPinToMap:
中,使用numberWithDouble
代替numberWithFloat
,使用viewDidLoad
,使用doubleValue
代替floatValue
。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];
}
for
中更新的viewDidLoad
循环将如下所示:
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];
}
答案 1 :(得分:0)
最初用户des不包含密钥的可变数组。因此,当访问密钥的对象时,请检查是否返回了非nil,否则创建一个新的可变数组来填充这些点。
答案 2 :(得分:0)
要解决仅删除其中一个标记的问题,Anna是正确的,您必须在创建方法中添加类似这样的行,以便查找标识符:
[pindict setObject:NAME_OF_YOUR_MARKER_TITLE forKey:@"name"];
然后执行以下操作以查看是否存在,将其从位置数组中删除,然后保存数据:
myMapAnnotation *selectedAnnotation = mapViewpin.annotation;
//Iterate through the location markers
for (int i = 0; i<pincoords.count; i++) {
if ([pincoords[i] containsObject: selectedAnnotation.title]) {
//Create a new mutable array to work with
NSMutableArray *pincoords = [[def objectForKey:@"saveCoords"]mutableCopy];
//Remove the marker
[pincoords removeObjectAtIndex:i];
[self.mapView removeAnnotation:selectedAnnotation];
//Update the data
[def setObject:pincoords forKey:@"saveCoords"];
}
//Sync outside the loop
[def synchronize];
}