【发布时间】:2013-11-18 04:37:02
【问题描述】:
我正在进行willChangeValueForKey 和didChangeValueForKey 调用,但即使使用它们,mapView 委托也不会通过mapView: viewForAnnotation: 来更新事物。如何强制更新MKAnnotation?
annotationView.image 不会在图像更改时更新,annotationView.image 也不会更新。据我的 NSLog 行所知,mapView: viewForAnnotation: 在更新 MKAnnotation 时不会再次被调用。
.h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@interface MapAnnotation : NSObject <MKAnnotation>
@property (nonatomic, assign) CLLocationCoordinate2D coordinate;
@property (nonatomic, retain) NSString *currentTitle;
@property (nonatomic, retain) NSString *currentSubTitle;
@property (nonatomic, retain) NSString *category;
@property (nonatomic, retain) NSString *pin;
- (NSString*) title;
- (NSString*) subtitle;
- (id) initWithCoordinate:(CLLocationCoordinate2D) c;
- (CLLocationCoordinate2D) getCoordinate;
- (void) addPlace:(MapAnnotation*) place;
- (int) placesCount;
- (void) cleanPlaces;
- (UIImage *) getPin;
@end
.m
#import "MapAnnotation.h"
@interface MapAnnotation()
@property (strong) NSMutableArray *places;
@end
@implementation MapAnnotation
@synthesize coordinate = _coordinate;
@synthesize currentTitle = _currentTitle;
@synthesize currentSubTitle = _currentSubTitle;
@synthesize places = _places;
@synthesize category = _category;
@synthesize pin = _pin;
- (NSString*) subtitle {
if ([self placesCount] == 1) {
return self.currentSubTitle;
}
else{
return @"";
}
}
- (NSString*) title {
if ([self placesCount] == 1) {
return self.currentTitle;
}
else{
return [NSString stringWithFormat:@"%d places", [self placesCount]];
}
}
- (void)addPlace:(MapAnnotation *)place {
[self willChangeValueForKey:@"title"];
[self willChangeValueForKey:@"subtitle"];
[self.places addObject:place];
[self didChangeValueForKey:@"title"];
[self didChangeValueForKey:@"subtitle"];
}
- (CLLocationCoordinate2D)getCoordinate {
return self.coordinate;
}
- (void)cleanPlaces {
[self willChangeValueForKey:@"title"];
[self willChangeValueForKey:@"subtitle"];
[self.places removeAllObjects];
[self.places addObject:self];
[self didChangeValueForKey:@"title"];
[self didChangeValueForKey:@"subtitle"];
}
- (id)initWithCoordinate:(CLLocationCoordinate2D) c {
self.coordinate=c;
self.places=[[NSMutableArray alloc] initWithCapacity:0];
return self;
}
- (int)placesCount {
return [self.places count];
}
- (UIImage *)getPin {
// begin a graphics context of sufficient size
CGSize size = CGSizeMake(26, 26);
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
// get the context for CoreGraphics
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGRect imageRect = CGRectMake(0, 0, size.width, size.height);
// Draw Dot
CGRect circleRect = CGRectInset(imageRect, 4, 4);
[[UIColor blackColor] setStroke];
[[UIColor yellowColor] setFill];
CGContextFillEllipseInRect(ctx, circleRect);
CGContextStrokeEllipseInRect(ctx, circleRect);
// Dot Content
[[UIColor blackColor] setStroke];
[[UIColor blackColor] setFill];
CGAffineTransform transform = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, 0.0);
CGContextSetTextMatrix(ctx, transform);
CGContextSetLineWidth(ctx, 2.0);
CGContextSetCharacterSpacing(ctx, 1.7);
CGContextSetTextDrawingMode(ctx, kCGTextFill);
UIFont *font = [UIFont fontWithName:@"Arial" size:11.0];
if ([self placesCount] != 1) {
NSString *label = [NSString stringWithFormat:@"%d", [self placesCount]];
CGSize stringSize = [label sizeWithAttributes:@{NSFontAttributeName:font}];
[label drawAtPoint:CGPointMake(size.width / 2 - stringSize.width / 2, size.height / 2 - stringSize.height / 2)
withAttributes:@{NSFontAttributeName:font}];
} else {
NSString *label = [NSString stringWithFormat:@"%@", self.pin];
CGSize stringSize = [label sizeWithAttributes:@{NSFontAttributeName:font}];
[label drawAtPoint:CGPointMake(size.width / 2 - stringSize.width / 2, size.height / 2 - stringSize.height / 2)
withAttributes:@{NSFontAttributeName:font}];
}
// make image out of bitmap context
UIImage *retImage = UIGraphicsGetImageFromCurrentImageContext();
// free the context
UIGraphicsEndImageContext();
return retImage;
}
@end
mapView:viewForAnnotation:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"MyAnnoation"];
if(!annotationView) {
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"MyAnnoation"];
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
}
annotationView.enabled = YES;
if ([(MapAnnotation*)annotation placesCount] == 1) {
annotationView.canShowCallout = YES;
}
annotationView.image = [(MapAnnotation*)annotation getPin];
NSLog(@"%@", [annotation title]);
return annotationView;
}
【问题讨论】:
-
只有注释视图的 callout 会自动观察标题和副标题的变化。视图本身(包括图像)不会观察这些属性,也不会自动更新视图。您是否使用自定义注释视图(以及自定义注释)?视图是否观察到标题和副标题的变化?显示 viewForAnnotation 方法。或者,您可以在更新注释时手动更新视图。
-
@AnnaKarenina - 目前没有自定义视图。我的问题是我正在更改注释图标,而不是更新。我将添加更多代码。
标签: ios mkmapview mkannotation