ios - 自定义注释在更新时不会在 map View 上更新
<p><p>我正在执行 <code>willChangeValueForKey</code> 和 <code>didChangeValueForKey</code> 调用,但即使使用它们,mapView 委托(delegate)也永远不会通过 <code>mapView: viewForAnnotation:</code> 来更新事情。如何强制更新 <code>MKAnnotation</code>?</p>
<p><code>annotationView.image</code> 不会在图像更改时更新,<code>annotationView.image</code> 也不会更新。据我的 NSLog 行所知,当 <code>MKAnnotation</code> 更新时,<code>mapView: viewForAnnotation:</code> 不会再次被调用。</p>
<p><strong>.h</strong></p>
<pre><code>#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
</code></pre>
<p><strong>.m</strong></p>
<pre><code>#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 ( == 1) {
return self.currentSubTitle;
}
else{
return @"";
}
}
- (NSString*) title {
if ( == 1) {
return self.currentTitle;
}
else{
return ];
}
}
- (void)addPlace:(MapAnnotation *)place {
;
;
;
;
;
}
- (CLLocationCoordinate2D)getCoordinate {
return self.coordinate;
}
- (void)cleanPlaces {
;
;
;
;
;
;
}
- (id)initWithCoordinate:(CLLocationCoordinate2D) c {
self.coordinate=c;
self.places=[ initWithCapacity:0];
return self;
}
- (int)placesCount {
return ;
}
- (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);
[ setStroke];
[ setFill];
CGContextFillEllipseInRect(ctx, circleRect);
CGContextStrokeEllipseInRect(ctx, circleRect);
// Dot Content
[ setStroke];
[ 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 = ;
if ( != 1) {
NSString *label = ];
CGSize stringSize = ;
[label drawAtPoint:CGPointMake(size.width / 2 - stringSize.width / 2, size.height / 2 - stringSize.height / 2)
withAttributes:@{NSFontAttributeName:font}];
} else {
NSString *label = ;
CGSize stringSize = ;
[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
</code></pre>
<p><strong>mapView:viewForAnnotation:</strong></p>
<pre><code>- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
MKAnnotationView *annotationView = ;
if(!annotationView) {
annotationView = [ initWithAnnotation:annotation reuseIdentifier:@"MyAnnoation"];
annotationView.rightCalloutAccessoryView = ;
}
annotationView.enabled = YES;
if ([(MapAnnotation*)annotation placesCount] == 1) {
annotationView.canShowCallout = YES;
}
annotationView.image = [(MapAnnotation*)annotation getPin];
NSLog(@"%@", );
return annotationView;
}
</code></pre></p>
<br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
<p><p>正如评论中提到的,除了 <code>title</code> 和 <code>subtitle</code> 之外,注释属性的更改不会自动导致 View 更新。</p>
<p>更改 <code>title</code> 和 <code>subtitle</code> 将在显示时自动更新标注,只要更改导致 KVO 通知(例如,如果使用带有 <code>ann.title = xxx</code> 或通过手动发出 KVO 通知,因为您有自定义 getter)。</p>
<p>要自动更新图像,您可能需要使用自定义注释 View 来观察底层注释属性的变化并自行刷新(在 <code>init</code> 中调用 <code>addObserver</code> ,在<code>observeValueForKeyPath</code>更新图片,在<code>dealloc</code>调用<code>removeObserver</code>)。您也可以使用非 KVO 方法,例如自定义通知或委托(delegate)(但仍使用自定义注释 View )来实现。</p>
<p>使用现有代码,在不创建自定义注释 View 和使用KVO等的情况下,快速手动更新注释 View 的方法是在注释更新后立即获取注释的当前 View 并更新<code>图像</code> 属性。只要 <code>viewForAnnotation</code> 中的代码与设置 <code>image</code> 的逻辑相同,这应该可以工作。</p>
<p>我假设在应用程序的某个地方(有时<em>在</em>注释已经添加),它通过调用<code>addPlace</code>来更新注释中的位置。之后,您可以尝试以下操作:</p>
<pre><code>;
//obtain the current view of someExistingAnnotation...
MKAnnotationView *av = ;
//update its image property to force refresh...
av.image = ;
//also set canShowCallout (it might have been NO)
</code></pre>
<p><br/>
不相关但当前的 <code>viewForAnnotation</code> 不能正确处理可能的 View 重用和/或除您的自定义注释之外的注释类型(例如会导致当前代码崩溃的用户位置蓝点)。我建议将其更改为:</p>
<pre><code>- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
if (! ])
{
//annotation is NOT a "MapAnnotation", return nil for default view...
return nil;
}
MKAnnotationView *annotationView = ;
if(!annotationView) {
annotationView = [ initWithAnnotation:annotation reuseIdentifier:@"MyAnnoation"];
annotationView.rightCalloutAccessoryView = ;
}
//update view's annotation to current in case it's being re-used
annotationView.annotation = annotation;
annotationView.enabled = YES;
if ([(MapAnnotation*)annotation placesCount] == 1) {
annotationView.canShowCallout = YES;
}
else {
annotationView.canShowCallout = NO;
}
annotationView.image = [(MapAnnotation*)annotation getPin];
NSLog(@"%@", );
return annotationView;
}
</code></pre></p>
<p style="font-size: 20px;">关于ios - 自定义注释在更新时不会在 mapView 上更新,我们在Stack Overflow上找到一个类似的问题:
<a href="https://stackoverflow.com/questions/20026321/" rel="noreferrer noopener nofollow" style="color: red;">
https://stackoverflow.com/questions/20026321/
</a>
</p>
页:
[1]