如何解决MapKit注释视图标签出库时更改位置/在错误的注释中显示
我要在地图图钉下方添加标签,以显示图钉的某些细节。我这样做是通过将UILabel添加为注释视图的子视图并将其行数设置为0以便在同一标签上显示多行来实现的。我遇到了一个问题,即地图最初正在加载正确的注释,并且我可以在地图图钉的标签中看到正确的数据,但是当我导航到其他屏幕然后返回到地图时,地图图钉是都在正确的位置,但是它们下面的标签不再在标签中显示正确的数据,它们都被混淆了。地图图钉开始显示属于其他地图图钉的数据。另外,如果我稍微移动一下地图,然后回到同一图钉,也会发生同样的事情。
我正在将数据添加到viewForAnnotation方法的标签中:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
// Return the view marker different for editing items ie draggable undragrable.
if ([annotation isKindOfClass:[PSMapAnnotation class]] == YES) {
PSMapAnnotation *senderAnnotation = (PSMapAnnotation *)annotation;
PSMapAnnotationView *annotationView = (PSMapAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:[senderAnnotation getPinKey]];
if (annotationView == nil) {
annotationView = [[PSMapAnnotationView alloc]
initWithAnnotation:senderAnnotation
reuseIdentifier:[senderAnnotation getPinKey]];
// THIS LINE RETURNS A STRING ARRAY CONTAINING LABEL DATA
NSMutableArray *taggedAnswers = [self _getTaggedAnswersForMarkerLabel:annotationView];
annotationView.enabled = YES;
annotationView.canShowCallout = NO;
UILabel *annotationLabel = [[UILabel alloc] init];
annotationLabel.text = @"";
annotationLabel.numberOfLines = 0;
annotationLabel.font = [UIFont fontWithName:@"HelveticaNeue" size:14.0];
annotationLabel.textColor = [UIColor blackColor];
annotationLabel.textAlignment = NSTextAlignmentCenter;
// LOOP THROUGH STRING ARRAY AND ADD ALL STRINGS TO ANNOTATION LABEL
for (Nsstring* taggedAnswer in taggedAnswers)
{
Nsstring *textToShow = [Nsstring stringWithFormat: @"%@\n",taggedAnswer];
annotationLabel.text = [annotationLabel.text stringByAppendingString: textToShow];
}
[annotationLabel sizetoFit];
annotationLabel.center = CGPointMake(annotationView.center.x,annotationView.center.y);
annotationView.myLabel = annotationLabel;
[annotationView addSubview:annotationLabel];
[annotationView setAnnotation:annotation];
}
else {
[annotationView setAnnotation:annotation];
}
return annotationView;
解决方法
用于配置注释视图的所有代码都在if (annotationView == nil) { ... }
块内。因此,如果它成功地重用了注释视图(您的else
块),则您无需设置标签。
您应将annotationLabel.text = ...
代码移到此if
语句之外。例如
if (annotationView == nil) {
// instantiate annotation view and add subview,but don’t set the `text` of the label yet
} else {
annotationView.annotation = annotation;
}
annotationView.annotationLabel.text = ...
例如
// CustomAnnotationView.h
@import UIKit;
@import MapKit;
@interface CustomAnnotationView : MKPinAnnotationView
@end
和
// CustomAnnotationView.m
#import "CustomAnnotationView.h"
@interface CustomAnnotationView ()
@property (nonatomic) UILabel *label;
@end
@implementation CustomAnnotationView
- (instancetype)initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
if (self) {
self.enabled = YES;
self.canShowCallout = NO;
self.label = [[UILabel alloc] init];
self.label.translatesAutoresizingMaskIntoConstraints = false;
self.label.text = @"";
self.label.numberOfLines = 0;
self.label.font = [UIFont fontWithName:@"HelveticaNeue" size:14.0];
self.label.textColor = [UIColor labelColor];
self.label.textAlignment = NSTextAlignmentCenter;
[self addSubview:self.label];
[NSLayoutConstraint activateConstraints:@[
[self.label.topAnchor constraintEqualToAnchor:self.bottomAnchor constant:8],[self.label.centerXAnchor constraintEqualToAnchor:self.centerXAnchor constant:-self.centerOffset.x]
]];
[self updateForAnnotation:annotation];
}
return self;
}
- (void)setAnnotation:(id<MKAnnotation>)annotation {
[super setAnnotation:annotation];
[self updateForAnnotation:annotation];
}
- (void)updateForAnnotation:(id<MKAnnotation>)annotation {
self.label.text = annotation.title;
}
@end
结果是:
您可以根据自己的意愿显然地对其进行自定义,但希望它可以说明这一想法。
请注意使用约束来确保标签始终居中。
也许不用说,这里我使用的是注释的title
属性,但是您可以检查注释子类并获取想要的任何属性,例如您的textToShow
。但是,考虑到已经存在将文本字符串与注释相关联的属性,title
(如果需要,可以选择subtitle
),我会使用它。
您可能考虑将标签添加项移至PSMapAnnotationView
的init方法中,因此注释视图将负责配置其子视图。而且,您可以覆盖annotation
的{{1}}属性的设置方法,以为您设置标签文本。
这样做的好处是(a)简化了PSMapAnnotationView
代码; (b)将子视图配置保留在其所属的位置; (c)如果仅支持iOS 11及更高版本,则可以彻底消除MKMapViewDelegate
。例如。在viewForAnnotation
中添加一行:
viewDidLoad
然后您可以完全删除[self.mapView registerClass:[CustomAnnotationView class] forAnnotationViewWithReuseIdentifier:MKMapViewDefaultAnnotationViewReuseIdentifier];
(除非您需要支持多种注释类型)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。