试图在MKMapView中查找用户位置的问题

时间:2010-12-01 07:23:23

标签: ios mkmapview cllocationmanager

我在尝试让用户的当前位置显示在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中设置的屏幕:

alt text

非常感谢任何帮助。谢谢!

1 个答案:

答案 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...
}