Files
ln-ios/ln_jq_app/ios/AMapNavIOSSDK/AMapNavIOSSDK/Classes/Class/ACustomAnnotationView.m

178 lines
5.9 KiB
Objective-C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//
// ACustomAnnotationView.m
// AMapNavIOSSDK
//
// Created by admin on 2026/3/17.
//
#import "ACustomAnnotationView.h"
// ─── 布局常量 ─────────────────────────────────────────────────────────────────
static const CGFloat kIconSize = 30; // 图标宽高
static const CGFloat kIconTextGap = 6.0; // 图标与文字间距
static const CGFloat kMaxTextWidth = 100.0; // 文字区域最大宽度
static const CGFloat kMaxTextLines = 2; // 最多行数
static const CGFloat kVPad = 4.0; // 整体上下内边距(用于 centerOffset 微调)
@interface ACustomAnnotationView ()
@property (nonatomic, strong) UIImageView *iconView;
@property (nonatomic, strong) UILabel *titleLabel;
/// 当前是否选中(用于更新图标 & 文字样式)
@property (nonatomic, assign) BOOL isAnnotationSelected;
@end
@implementation ACustomAnnotationView
#pragma mark - Init / Reuse
- (instancetype)initWithAnnotation:(id<MAAnnotation>)annotation
reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
if (self) {
self.backgroundColor = [UIColor clearColor];
// 关闭 MAAnnotationView 自带的 image 渲染,避免干扰
self.image = nil;
[self _buildSubviews];
[self _updateFromAnnotation];
[self setNeedsLayout];
}
return self;
}
- (void)setAnnotation:(id<MAAnnotation>)annotation {
[super setAnnotation:annotation];
[self _updateFromAnnotation];
[self setNeedsLayout];
}
#pragma mark - Build
- (void)_buildSubviews {
// ── 图标 ──────────────────────────────────────────────────
if (!self.iconView) {
UIImageView *iv = [[UIImageView alloc] init];
iv.contentMode = UIViewContentModeScaleAspectFit;
[self addSubview:iv];
self.iconView = iv;
}
// ── 文字 ──────────────────────────────────────────────────
if (!self.titleLabel) {
UILabel *lbl = [[UILabel alloc] init];
lbl.numberOfLines = kMaxTextLines;
lbl.lineBreakMode = NSLineBreakByTruncatingTail;
lbl.textAlignment = NSTextAlignmentLeft;
[self addSubview:lbl];
self.titleLabel = lbl;
}
// 初始化为默认(未选中)样式
[self _applyStyle:NO];
}
/// 根据选中状态切换图标 & 文字样式
- (void)_applyStyle:(BOOL)selected {
if (selected) {
self.iconView.image = [AMapNavCommonUtil imageWithName3x:@"station_select_icon"];
self.titleLabel.font = [UIFont boldSystemFontOfSize:14];
self.titleLabel.textColor = [UIColor colorWithWhite:0.12 alpha:1.0];
} else {
self.iconView.image = [AMapNavCommonUtil imageWithName3x:@"station_normal_icon"];
self.titleLabel.font = [UIFont systemFontOfSize:13];
self.titleLabel.textColor = [UIColor colorWithWhite:0.25 alpha:1.0];
}
}
#pragma mark - Data
- (void)_updateFromAnnotation {
NSString *text = nil;
id<MAAnnotation> ann = self.annotation;
if ([ann respondsToSelector:@selector(title)]) {
text = ann.title;
}
if (text.length == 0) {
text = @"加氢站";
}
self.titleLabel.text = text;
}
#pragma mark - SelectionMAAnnotationView 官方选中回调)
- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
[super setSelected:selected animated:animated];
self.isAnnotationSelected = selected;
[self _applyStyle:selected];
[self setNeedsLayout];
}
#pragma mark - Layout
- (void)layoutSubviews {
[super layoutSubviews];
// 文字最大 100pt、最多 2 行
CGSize textConstraint = CGSizeMake(kMaxTextWidth,
CGFLOAT_MAX);
CGSize textFit = [self.titleLabel sizeThatFits:textConstraint];
// 高度上限2 行
CGFloat lineH = self.titleLabel.font.lineHeight;
CGFloat maxTextH = lineH * kMaxTextLines
+ self.titleLabel.font.leading * (kMaxTextLines - 1);
CGFloat textW = MIN(textFit.width, kMaxTextWidth);
CGFloat textH = MIN(textFit.height, maxTextH);
CGFloat totalW = kIconSize + kIconTextGap + textW;
CGFloat totalH = MAX(kIconSize, textH) + kVPad * 2;
// 更新自身 bounds
self.bounds = CGRectMake(0, 0, totalW, totalH);
// 图标:垂直居中
CGFloat iconY = (totalH - kIconSize) * 0.5;
self.iconView.frame = CGRectMake(0, iconY, kIconSize, kIconSize);
// 文字:垂直居中
CGFloat textY = (totalH - textH) * 0.5;
self.titleLabel.frame = CGRectMake(kIconSize + 1, textY, textW, textH);
// 锚点:让图标底部对齐地图坐标点
// MAAnnotationView 的 centerOffset 以 (0,0)=中心 为原点
// 默认选中图标底部对准坐标:向上偏移 totalH/2
self.centerOffset = CGPointMake(totalW / 2.0 - kIconSize / 2.0,
-(totalH / 2.0));
}
#pragma mark - Hit Test
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
UIView *hit = [super hitTest:point withEvent:event];
if (hit == self || [hit isDescendantOfView:self]) {
return self;
}
return hit;
}
#pragma mark - Touch
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[super touchesBegan:touches withEvent:event];
id<MAAnnotation> annotation = self.annotation;
if (!annotation) return;
UIView *sv = self.superview;
while (sv && ![sv isKindOfClass:[MAMapView class]]) {
sv = sv.superview;
}
MAMapView *mapView = (MAMapView *)sv;
if (!mapView) return;
// [mapView deselectAnnotation:annotation animated:NO];
}
@end