- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在执行 willChangeValueForKey
和 didChangeValueForKey
调用,但即使使用它们,mapView 委托(delegate)也永远不会运行通过 mapView: viewForAnnotation:
来更新事情。如何强制更新 MKAnnotation
?
当图像更改时,annotationView.image
不会更新,annotationView.image
也不会更新。据我所知,通过我的 NSLog 行,当 MKAnnotation
更新时,mapView: viewForAnnotation:
不会被再次调用。
.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
map View :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;
}
最佳答案
如评论中所述,除了 title
和 subtitle
之外,注释属性的更改不会自动导致 View 更新。
更改 title
和 subtitle
将在显示时自动更新标注,只要更改导致 KVO 通知(例如,如果使用带有 ann.title = xxx
或通过手动发出 KVO 通知作为问题中的代码,因为您有自定义 getter)。
要自动更新图像,您可能需要使用自定义注释 View 来观察底层注释属性的变化并自行刷新(在 init
中调用 addObserver
, 在 observeValueForKeyPath
更新图像, 在 dealloc
调用 removeObserver
).您也可以使用非 KVO 方法来完成它,例如自定义通知或委托(delegate)(但仍然使用自定义注释 View )。
在现有代码中,无需创建自定义注解 View 和使用KVO等即可快速手动更新注解 View 的方法是在注解更新后立即获取注解的当前 View 并更新图像
属性。只要 viewForAnnotation
中的代码与设置 image
的逻辑相同,这就应该有效。
我假设在应用程序的某处(有时在注释已添加之后),它正在通过调用 addPlace
更新注释中的位置。之后,您可以尝试以下操作:
[someExistingAnnotation addPlace:anotherPlace];
//obtain the current view of someExistingAnnotation...
MKAnnotationView *av = [mapView viewForAnnotation:someExistingAnnotation];
//update its image property to force refresh...
av.image = [someExistingAnnotation getPin];
//also set canShowCallout (it might have been NO)
不相关,但当前的 viewForAnnotation
没有正确处理可能的 View 重用和/或自定义注释以外的注释类型(例如用户位置蓝点,这会导致当前代码崩溃)。我建议将其更改为:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
if (! [annotation isKindOfClass:[MapAnnotation class]])
{
//annotation is NOT a "MapAnnotation", return nil for default view...
return nil;
}
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:@"MyAnnoation"];
if(!annotationView) {
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"MyAnnoation"];
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
}
//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(@"%@", [annotation title]);
return annotationView;
}
关于ios - 更新时自定义注释不会在 map View 上更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20026321/
尝试使用集成到 QTCreator 的表单编辑器,但即使我将插件放入 QtCreator.app/Contents/MacOS/designer 也不会显示。不过,相同的 dylib 文件确实适用于独
在此代码示例中。 “this.method2();”之后会读到什么?在返回returnedValue之前会跳转到method2()吗? public int method1(int returnedV
我的项目有通过gradle配置的依赖项。我想添加以下依赖项: compile group: 'org.restlet.jse', name: 'org.restlet.ext.apispark', v
我将把我们基于 Windows 的客户管理软件移植到基于 Web 的软件。我发现 polymer 可能是一种选择。 但是,对于我们的使用,我们找不到 polymer 组件具有表格 View 、下拉菜单
我的项目文件夹 Project 中有一个文件夹,比如 ED 文件夹,当我在 Eclipse 中指定在哪里查找我写入的文件时 File file = new File("ED/text.txt"); e
这是奇怪的事情,这个有效: $('#box').css({"backgroundPosition": "0px 250px"}); 但这不起作用,它只是不改变位置: $('#box').animate
这个问题在这里已经有了答案: Why does OR 0 round numbers in Javascript? (3 个答案) 关闭 5 年前。 Mozilla JavaScript Guide
这个问题在这里已经有了答案: Is the function strcmpi in the C standard libary of ISO? (3 个答案) 关闭 8 年前。 我有一个问题,为什么
我目前使用的是共享主机方案,我不确定它使用的是哪个版本的 MySQL,但它似乎不支持 DATETIMEOFFSET 类型。 是否存在支持 DATETIMEOFFSET 的 MySQL 版本?或者有计划
研究 Seam 3,我发现 Seam Solder 允许将 @Named 注释应用于包 - 在这种情况下,该包中的所有 bean 都将自动命名,就好像它们符合条件一样@Named 他们自己。我没有看到
我知道 .append 偶尔会增加数组的容量并形成数组的新副本,但 .removeLast 会逆转这种情况并减少容量通过复制到一个新的更小的数组来改变数组? 最佳答案 否(或者至少如果是,则它是一个错
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
noexcept 函数说明符是否旨在 boost 性能,因为生成的对象中可能没有记录异常的代码,因此应尽可能将其添加到函数声明和定义中?我首先想到了可调用对象的包装器,其中 noexcept 可能会产
我正在使用 Angularjs 1.3.7,刚刚发现 Promise.all 在成功响应后不会更新 angularjs View ,而 $q.all 会。由于 Promises 包含在 native
我最近发现了这段JavaScript代码: Math.random() * 0x1000000 10.12345 10.12345 >> 0 10 > 10.12345 >>> 0 10 我使用
我正在编写一个玩具(物理)矢量库,并且遇到了 GHC 坚持认为函数应该具有 Integer 的问题。是他们的类型。我希望向量乘以向量以及标量(仅使用 * ),虽然这可以通过仅使用 Vector 来实现
PHP 的 mail() 函数发送邮件正常,但 Swiftmailer 的 Swift_MailTransport 不起作用! 这有效: mail('user@example.com', 'test
我尝试通过 php 脚本转储我的数据,但没有命令行。所以我用 this script 创建了我的 .sql 文件然后我尝试使用我的脚本: $link = mysql_connect($host, $u
使用 python 2.6.4 中的 sqlite3 标准库,以下查询在 sqlite3 命令行上运行良好: select segmentid, node_t, start, number,title
我最近发现了这段JavaScript代码: Math.random() * 0x1000000 10.12345 10.12345 >> 0 10 > 10.12345 >>> 0 10 我使用
我是一名优秀的程序员,十分优秀!