尝试在 MKMapView 中查找用户位置时出现问题

发布于 2024-10-05 21:48:54 字数 5029 浏览 2 评论 0原文

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

任何帮助都将非常感激。谢谢!

I am having problems trying to get the user's current position to display on an MKMapView. Here is the relevant code:

Header:

//  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

Implementation(partial):

//  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];
}

When running the application, the map view displays just fine with the annotations and everything, but when the current location button is pressed, the map re-centers to its new location(slight move) and a fraction of a second later, it crashes. When I comment out [mapView setShowsUserLocation:YES]; there is no problem, but otherwise it spits out this error in the console:

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'

Googling has indicated that this is most likely an IB problem but I have not been able to spot it. Here is a screen of my set up in IB:

alt text

Any help whatsoever will be very much appreciated. Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧人九事 2024-10-12 21:48:54

问题看起来像是在 viewForAnnotation 方法中。该代码尝试在 MKUserLocation 注释 上调用 annotationType (它没有这样的方法)。

viewForAnnotation 中,它应该检查请求的 view 是什么类型的注释并进行相应的处理。

但是,如果您使用 MKMapView,则无需使用 CLLocationManager 来获取用户的当前位置。只需将 showsUserLocation 设置为 YES 将使地图视图在用户所在位置显示一个蓝点。

无论哪种情况,viewForAnnotation 方法都需要首先检查注释类 类型。像这样的东西应该在顶部:

- (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...
}

The problem looks like it is in the viewForAnnotation method. The code is trying to call annotationType on the MKUserLocation annotation (which doesn't have such a method).

In viewForAnnotation, it should check what kind of annotation the view is being requested for and handle accordingly.

However, if you are using the MKMapView, you don't need to use CLLocationManager to get the user's current location. Just setting showsUserLocation to YES will make the map view show a blue dot where the user is located.

In either case, the viewForAnnotation method needs to check the annotation class type first. Something like this should be at the top:

- (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...
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文