문제 설명
MKMapView에서 사용자 위치를 찾는 데 문제가 있음 (Problems Trying to Find User Location in MKMapView)
사용자의 현재 위치를 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에서 설정한 화면입니다.
어떤 도움이든 대단히 감사하겠습니다. 감사합니다!
참조 솔루션
방법 1:
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...
}
(by Stunner、user467105)