我在尝试让用户的当前位置显示在MKMapView上时遇到问题。以下是相关代码:
标题
// ParkingMapViewController.m
#import <UIKit/UIKit.h>
#import <MapKit/MapKit.h>
@interface ParkingMapViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate> {
MKMapView *mapView;
CLLocationManager *locationManager;
}
@property (nonatomic, retain) IBOutlet MKMapView *mapView;
@property (nonatomic, retain) CLLocationManager *locationManager;
-(void)loadAnnotations;
-(void)showCurrentLocationButtonTapped:(id)sender;
@end
实施(部分):
// ParkingMapViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:100 target:self action:@selector(showCurrentLocationButtonTapped:)];
[self loadAnnotations];
CLLocationCoordinate2D centerCoord = { UCD_LATITUDE, UCD_LONGITUDE };
[mapView setCenterCoordinate:centerCoord zoomLevel:13 animated:NO]; //from "MKMapView+ZoomLevel.h"
}
- (void)showCurrentLocationButtonTapped:(id)sender {
NSLog(@"Showing current location.");
//[self.mapView setShowsUserLocation:YES];
//mapView.showsUserLocation = YES;
//[sender setEnabled:NO]; //TODO: Uncomment and test
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone; // whenever we move
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters; // 100 m
[locationManager startUpdatingLocation];
}
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
[mapView setCenterCoordinate:newLocation.coordinate];
if ([mapView showsUserLocation] == NO) {
[mapView setShowsUserLocation:YES];//when this line is commented, there is no problem
}
[mapView setCenterCoordinate:newLocation.coordinate zoomLevel:13 animated:YES];
}
- (void)viewDidUnload {
[super viewDidUnload];
[mapView setShowsUserLocation:NO];
}
- (void)dealloc {
[locationManager release];
[mapView release];
[super dealloc];
}
运行应用程序时,地图视图会显示注释和所有内容,但是当按下当前位置按钮时,地图会重新定位到其新位置(轻微移动),稍后一小段时间,它崩溃了。当我注释掉[mapView setShowsUserLocation:YES];
时没有问题,但是否则会在控制台中吐出此错误:
2010-11-30 22:57:20.657 Parking[53430:207] -[MKUserLocation annotationType]: unrecognized selector sent to instance 0x78427f0
2010-11-30 22:57:20.659 Parking[53430:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[MKUserLocation annotationType]: unrecognized selector sent to instance 0x78427f0'
*** Call stack at first throw:
(
0 CoreFoundation 0x0266ab99 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x027ba40e objc_exception_throw + 47
2 CoreFoundation 0x0266c6ab -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x025dc2b6 ___forwarding___ + 966
4 CoreFoundation 0x025dbe72 _CF_forwarding_prep_0 + 50
5 Parking 0x00003ddb -[ParkingMapViewController mapView:viewForAnnotation:] + 64
6 MapKit 0x023a8130 -[MKAnnotationContainerView _addViewForAnnotation:] + 175
7 MapKit 0x023a2b2a -[MKAnnotationContainerView _addViewsForAnnotations:animated:] + 251
8 MapKit 0x0239e657 -[MKAnnotationContainerView showAddedAnnotationsAnimated:] + 137
9 MapKit 0x0237837c -[MKMapView _showAddedAnnotationsAndRouteAnimated:] + 102
10 MapKit 0x02376a88 -[MKMapViewInternal delayedShowAddedAnnotationsAnimated] + 191
11 Foundation 0x000571c9 __NSFireTimer + 125
12 CoreFoundation 0x0264bf73 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 19
13 CoreFoundation 0x0264d5b4 __CFRunLoopDoTimer + 1364
14 CoreFoundation 0x025a9dd9 __CFRunLoopRun + 1817
15 CoreFoundation 0x025a9350 CFRunLoopRunSpecific + 208
16 CoreFoundation 0x025a9271 CFRunLoopRunInMode + 97
17 GraphicsServices 0x02f4900c GSEventRunModal + 217
18 GraphicsServices 0x02f490d1 GSEventRun + 115
19 UIKit 0x002cfaf2 UIApplicationMain + 1160
20 Parking 0x000020e0 main + 102
21 Parking 0x00002071 start + 53
)
terminate called after throwing an instance of 'NSException'
谷歌搜索表明这很可能是一个IB问题,但我无法发现它。这是我在IB中设置的屏幕:
非常感谢任何帮助。谢谢!
答案 0 :(得分:2)
问题看起来像viewForAnnotation
方法。代码正试图在annotationType
上调用MKUserLocation annotation
(没有这样的方法)。
在viewForAnnotation
中,它应该检查请求view
的注释类型并进行相应处理。
但是,如果您使用的是MKMapView
,则无需使用CLLocationManager
来获取用户的current location
。只需将showsUserLocation
设置为YES
,即可使map view
显示用户所在的蓝点。
在任何一种情况下,viewForAnnotation
方法都需要先检查annotation class
类型。像这样的东西应该在顶部:
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation
{
if ([annotation isKindOfClass:MKUserLocation.class]) {
//it's the built-in user location annotation, return nil to get default blue dot...
return nil;
}
//handle your custom annotations...
}