我想为我的自定义 MKAnnotationView 同步加载图像;我已经在使用 EGOImageView 框架(它与 UITableViews 配合得很好),但我无法让它在 MKMapView 上工作。图像似乎已加载,但我无法在地图上刷新它们 -[myMap setNeedsDisplay]
什么也不做。
7 回答
我自己没有尝试过,但它可能会起作用:
使用 MKMapView 方法获取注释视图并为其- (MKAnnotationView *)viewForAnnotation:(id <MKAnnotation>)annotation
设置新图像。
编辑:我自己尝试这样做,这种方法对我来说效果很好:
// Function where you got new image and want to set it to annotation view
for (MyAnnotationType* myAnnot in myAnnotationContainer){
MKAnnotationView* aView = [mapView viewForAnnotation: myAnnot];
aView.image = [UIImage imageNamed:@"myJustDownloadedImage.png"];
}
调用此方法后,所有注释图像都已更新。
我发现只有一种更新注释的可靠方法,其他方法对我不起作用:只需再次删除和添加注释:
id <MKAnnotation> annotation;
// ...
[mapView removeAnnotation:annotation];
[mapView addAnnotation:annotation];
此代码将使 -[mapView:viewForAnnotation:] 再次被调用,因此您的注释视图将被再次创建(或者如果您使用 dequeueReusableAnnotationViewWithIdentifier 则可能被重用)并具有正确的数据。
这是我发现强制重绘 MKAnnotationViews 的唯一方法:
// 强制更新地图视图(否则注释视图不会重绘)
CLLocationCoordinate2D 中心 = mapView.centerCoordinate;
mapView.centerCoordinate = 中心;
似乎没用,但它确实有效。
这对我有用
#import "EGOImageView.h"
- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation
{
//ENTER_METHOD;
if([annotation isKindOfClass:[MKUserLocation class]]) return nil;
MKPinAnnotationView *annView;
static NSString *reuseIdentifier = @"reusedAnnView";
annView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
annView.canShowCallout = YES;
annView.calloutOffset = CGPointMake(-5.0f, 0.0f);
annView.opaque = NO;
annView.image = [[UIImage imageNamed:@"tempImage.png"] retain];
YourModel *p = annotation; // make this conform to <MKAnnotation>
EGOImageView *egoIV = [[EGOImageView alloc] initWithPlaceholderImage:[UIImage imageNamed:@"tempImage.png"]];
[egoIV setDelegate:self];
egoIV.imageURL = [NSURL URLWithString:p.theUrlToDownloadFrom];
[annView addSubview:egoIV];
[egoIV release];
return [annView autorelease];
}
(我不知道如何表明这篇文章与 zerodiv 的答案有关。)我能够通过添加各种 kickstart 来让 zerodiv 的方法工作,强制一个无意义但不同的坐标,然后恢复之前的正确坐标。由于第一个位置,屏幕根本不闪烁。
CLLocationCoordinate2D center = mapView.centerCoordinate;
CLLocationCoordinate2D forceChg;
forceChg.latitude = 0;
forceChg.longitude = curLongNum;
mapView.centerCoordinate = forceChg;
mapView.centerCoordinate = center;
谢谢@Vladimir 的帮助!你的回答启发了我的回答。我做了一些更改以使其更清晰。
func addAnnotation(coordinate: CLLocationCoordinate2D) {
let annotation = Annotation()
annotation.coordinate = coordinate
annotations.append(annotation)
mapView.addAnnotation(annotation)
for index in 0..<annotations.count {
if let view = mapView.view(for: annotations[index]) as? AnnotationView {
if index == 0 {
view.imageView.image = NSImage(named: "icon_positioning")
} else {
view.imageView.image = NSImage(named: "icon_positioning")
}
}
}
}
MKMapview 中的协议也需要实现:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let view = mapView.dequeueReusable(withClass: AnnotationView.self, annotation: annotation)
if index == 0 {
view.imageView.image = NSImage(named: "icon_positioning")
} else {
view.imageView.image = NSImage(named: "icon_positioning")
}
return view
}
顺便说一下,这里的 AnnotationView 初始化是:
public extension MKMapView {
func dequeueReusable<T: MKAnnotationView>(withClass name: T.Type,annotation: MKAnnotation?) -> T {
if let view = dequeueReusableAnnotationView(withIdentifier: T.identifier()) as? T {
return view
}
let view = T.init(annotation: annotation, reuseIdentifier: T.identifier())
return view
}
}
再次感谢@Vladimir 的回答
我想用新选择的头像刷新用户位置图钉。我为这种情况找到了另一种快速解决方案。我有 2 个屏幕。第一个用于选择头像,第二个用于在地图上显示用户。
swift 5您可以通过创建MKAnnotationView 来更改用户位置图像
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
let userIdentifier = "UserLocation"
var userView = mapView.dequeueReusableAnnotationView(withIdentifier: userIdentifier)
if userView == nil {
userView = MKAnnotationView(annotation: annotation, reuseIdentifier: userIdentifier)
} else {
userView?.annotation = annotation
}
userView!.image = UIImage(named: "avatar1") //your image
return userView
}
return nil
}
因此,如果用户将头像更改为其他内容,例如“avatar2”,它将不会刷新。
为了刷新用户位置图像,我在viewWillAppear()中添加了此代码
self.mapView.showsUserLocation = false
self.mapView.showsUserLocation = true