2

我正在開發一個iphone應用程序使用mapkit和CLLocationManager。MKAnnotationView更新標題和字幕與事件接收的距離

我在地圖上放了很多MKPinAnnotationView(約100),我想在收到它時更新所有標註的用戶距離的標題。

怎麼辦?

感謝


我試試這個更新與新的位置標註的字幕,但它沒有工作。

在我MyAppDelegate.h

extern NSString * const GMAP_USERLOCATION_CHANGED; 

@interface MyAppDelegate : NSObject <UIApplicationDelegate> { 
    CLLocationManager *locationManager; 
    CLLocation *userLocation; 
} 
@property (nonatomic, retain) CLLocationManager *locationManager; 
@property (nonatomic, retain) CLLocation *userLocation; 
@end 

在我MyAppDelegate.m

@implementation MyAppDelegate 

NSString * const GMAP_USERLOCATION_CHANGED = @"gMapUserLocationChanged"; 
@synthesize locationManager, userLocation; 

- (void)applicationDidFinishLaunching:(UIApplication *)application 
{  
    userLocation = nil; 
    [[self locationManager] startUpdatingLocation]; 

    [window addSubview:tabBarController.view]; 
    [window makeKeyAndVisible]; 
} 

#pragma mark - 
#pragma mark Core Location delegate 
- (CLLocationManager *)locationManager 
{ 
    if (locationManager != nil) 
{ 
     return locationManager; 
    } 

    locationManager = [[CLLocationManager alloc] init]; 
    locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters; 
    locationManager.delegate = self; 

    return locationManager; 
} 

- (void)locationManager:(CLLocationManager *)manager 
    didUpdateToLocation:(CLLocation *)newLocation 
        fromLocation:(CLLocation *)oldLocation 
{ 
self.userLocation = newLocation; 
// send notification to defaulcenter 
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 
[nc postNotificationName:GMAP_USERLOCATION_CHANGED object:self.userLocation]; 
} 


- (void)dealloc { 
    [window release]; 
    [locationManager release]; 
    [userLocation release]; 

    [super dealloc]; 
} 

@end 

我做了一個名爲MyAnnotation customAnnotationView。

在MyAnnotation.h

@interface MyAnnotation : MKPinAnnotationView<MKAnnotation> 
{ 
double longitude; 
double latitude; 
NSString *title; 
NSString *subtitle; 

} 

@property (nonatomic, retain) NSString *title; 
@property (nonatomic, retain) NSString *subtitle; 
@property double longitude; 
@property double latitude; 
@end 

在MyAnnotation.m:

#import "MyAnnotation.h" 
#import "MyAppDelegate.h" 

@implementation MyAnnotation 

@synthesize title, subtitle; 
@synthesize longitude; 
@synthesize latitude; 

-(id)initWithAnnotation:(id <MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier 
{ 
self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]; 
if (self != nil) 
{ 
    NSLog(@"add observer"); 
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 
    [nc addObserver:self selector:@selector(receivedNewUserLocation:) name:GMAP_USERLOCATION_CHANGED object:nil]; 
} 
return self; 
} 

- (void)setTitleAndSubtitle 
{ 
[self setTitleAndSubtitle:nil]; 
} 

- (id)setTitleAndSubtitle:(CLLocation*)userLocation 
{ 
CLLocationDistance dist = -1; 

if(userLocation) 
{ 
    CLLocation *poiLoc = [[CLLocation alloc] initWithLatitude:self.latitude longitude:self.longitude]; 
    dist = [userLocation distanceFromLocation:poiLoc]/1000; 
    NSLog(@"distance is now %.f", dist); 
} 

title = @"the Title of the poi!"; 

subtitle = [NSString stringWithFormat:@"Distance: %@", 
    dist > -1 ? [NSString stringWithFormat:@"%.2f km", dist] : @"-" 
    ]; 

return self; 
} 

- (void)receivedNewUserLocation:(NSNotification *)userLocationNotification 
{ 
CLLocation *userlocation = (CLLocation*)[userLocationNotification object]; 
[self setTitleAndSubtitle:userlocation]; 
} 

- (CLLocationCoordinate2D)coordinate; 
{ 
    CLLocationCoordinate2D theCoordinate; 
    theCoordinate.latitude = latitude; 
    theCoordinate.longitude = longitude; 
    return theCoordinate; 
} 

- (NSString *)title 
{ 
    return title; 
} 

- (NSString *)subtitle 
{ 
    return subtitle; 
} 

- (void)dealloc 
{ 
    [title release]; 
    [subtitle release]; 

    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; 
    [nc removeObserver:self]; 

    [super dealloc]; 
} 
@end 

最後,我用它一樣,在我的MapViewController(我只放了viewForAnnotation委託這裏的方法):

- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation 
{ 
    // if it's the user location, just return nil. 
    if ([annotation isKindOfClass:[MKUserLocation class]]) 
     return nil; 

    MyAnnotation *annotationView = nil; 
    MyAnnotation* myAnnotation = (MyAnnotation *)annotation; 
    // try to dequeue an existing pin view first 
    NSString* identifier = @"CustomMapAnnotation"; 
    MyAnnotation *customPinView = (MyAnnotation *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier]; 


    if(nil == customPinView) 
    { 
// if an existing pin view was not available, create one 
customPinView = [[[MyAnnotation alloc] 
    initWithAnnotation:myAnnotation 
    reuseIdentifier:identifier] 
    autorelease]; 

customPinView.animatesDrop = YES; 
customPinView.canShowCallout = YES; 
    } 

    annotationView = customPinView; 
    [annotationView setEnabled:YES]; 
    [annotationView setCanShowCallout:YES]; 

    return annotationView; 
} 

在mkannotation加載到地圖上後,所有此字幕都沒有更新... 。 怎麼了?

感謝您的幫助......

回答

2

這取決於你如何創建MKAnnotations。

你或許應該有這樣的Place.h和Place.m,這符合MKAnnotation協議爲代表的「廣場」的對象......

廣場將有沿

float distance; 
行屬性

然後你的字幕方法(MKAnnotation的一部分)會做這樣的事情

- (NSString *)subtitle 
{ 
    return [NSString stringWithFormat:@"%0.2f Miles Away", distance]; 
} 

那字幕方法被通過的MapView不斷呼籲(其實我因爲只要你操縱距離值,它就會反映在地圖上(也許早在下次你點擊這個圖釘時)。

+0

感謝您的解決方案。這似乎是一個不錯的解決方案。我之前想要嘗試使用CLLocationManager收到位置更新時,在我的mapviewcontroller中讀取註釋數組。但標題無法訪問。 關於刷新時間,我想將CLLocationManager添加到appdelegate中,它將更改它的屬性,然後使用觀察者監視此屬性,以在每次接收更新時更改位置。我會看看它是否工作。如果是這種情況,我會在這裏發佈解決方案... – Dragouf 2010-07-15 08:09:19

+0

仍然不適合我。任何人? – Dragouf 2010-07-22 09:11:10

+0

我認爲還有其他的缺失。是的,這將返回每個註釋的副標題的距離,但您必須在其他地方設置距離。 – marciokoko 2013-01-10 02:41:25

6

當您更新標題時,您應該通過MKAnnotationView更新標註視圖,方法是根據您最需要的KVO方式進行更新,例如,:

  1. 合成或實現制定者所有權和使用

    self.title = @"new title"; 
    
  2. 使用明確的志願通知

    [self willChangeValueForKey:@"title"]; 
    [title release]; 
    title = [newTitle copy]; 
    [self didChangeValueForKey:@"title"]; 
    

同上字幕。

相關問題