|
|
@@ -13,88 +13,125 @@ class MapAnnotationView: MKAnnotationView {
|
|
|
static let identifier: String = "MapAnnotationView"
|
|
|
|
|
|
var marker: ATMapMarker?
|
|
|
+ var markerImageView: MapAnnotationMarkerImageView!
|
|
|
+ var textView: MapAnnotationMarkerTextView?
|
|
|
+
|
|
|
+ // spacing between text and image
|
|
|
+ let spacing: CGFloat = 6
|
|
|
|
|
|
var annotationSelected: Bool {
|
|
|
return (marker?.isSelected ?? false) || self.isSelected
|
|
|
}
|
|
|
|
|
|
- private let imageView = UIImageView()
|
|
|
- private var uiImage: UIImage? {
|
|
|
- // 先尝试从主资源束加载
|
|
|
- let imageName = marker?.markerType.imageName(selected: annotationSelected) ?? ""
|
|
|
- print(imageName)
|
|
|
- if let image = UIImage(named: imageName) {
|
|
|
- return image
|
|
|
- }
|
|
|
-
|
|
|
- // 尝试从插件资源束加载
|
|
|
- let bundleURL = Bundle(for: MapAnnotationView.self).url(forResource: "map_mapkit_ios_resources", withExtension: "bundle")
|
|
|
- if let bundleURL = bundleURL, let resourceBundle = Bundle(url: bundleURL) {
|
|
|
- return UIImage(named: imageName, in: resourceBundle, compatibleWith: nil)
|
|
|
- }
|
|
|
-
|
|
|
- return nil
|
|
|
- }
|
|
|
-
|
|
|
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
|
|
|
self.marker = annotation as? ATMapMarker
|
|
|
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
|
|
|
|
|
|
self.isEnabled = marker?.markerType.supportSelected ?? false
|
|
|
self.isHidden = false
|
|
|
- // 添加图片显示
|
|
|
- setupImageView()
|
|
|
+ setupViews()
|
|
|
}
|
|
|
|
|
|
required init?(coder aDecoder: NSCoder) {
|
|
|
fatalError("init(coder:) has not been implemented")
|
|
|
}
|
|
|
|
|
|
- private func setupImageView() {
|
|
|
- // 设置默认图像
|
|
|
- imageView.image = uiImage
|
|
|
- imageView.contentMode = .scaleAspectFit
|
|
|
+ // MARK: - 设置视图
|
|
|
+
|
|
|
+ private func setupViews() {
|
|
|
+ // 创建并添加图像视图
|
|
|
+ markerImageView = MapAnnotationMarkerImageView(markerType: marker?.markerType ?? MarkerType.mine)
|
|
|
+ markerImageView.isSelected = annotationSelected
|
|
|
+ addSubview(markerImageView)
|
|
|
+
|
|
|
+ // 如果有标题,添加文本视图
|
|
|
+ if let markerName = marker?.markerName, !markerName.isEmpty {
|
|
|
+ textView = MapAnnotationMarkerTextView(text: markerName)
|
|
|
+ if let textView = textView {
|
|
|
+ addSubview(textView)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置AutoLayout
|
|
|
+ setupConstraints()
|
|
|
+ }
|
|
|
+
|
|
|
+ // MARK: - 布局
|
|
|
+
|
|
|
+ private func setupConstraints() {
|
|
|
+ // 禁用自动约束转换
|
|
|
+ translatesAutoresizingMaskIntoConstraints = false
|
|
|
+ markerImageView.translatesAutoresizingMaskIntoConstraints = false
|
|
|
|
|
|
- // 添加图像视图到注释视图
|
|
|
- addSubview(imageView)
|
|
|
+ let markerSize = marker?.markerType.size ?? CGSize(width: 30, height: 30)
|
|
|
|
|
|
- // 设置图像视图的大小和位置
|
|
|
- let size = marker?.markerType.size ?? .init()
|
|
|
- imageView.frame = CGRect(origin: .init(), size: size)
|
|
|
+ // 设置图像视图约束 - 居中显示在标记视图中
|
|
|
+ NSLayoutConstraint.activate([
|
|
|
+ markerImageView.centerXAnchor.constraint(equalTo: centerXAnchor),
|
|
|
+ markerImageView.centerYAnchor.constraint(equalTo: centerYAnchor),
|
|
|
+ markerImageView.widthAnchor.constraint(equalToConstant: markerSize.width),
|
|
|
+ markerImageView.heightAnchor.constraint(equalToConstant: markerSize.height)
|
|
|
+ ])
|
|
|
+
|
|
|
+ // 设置文本视图约束 - 位于图像上方,居中对齐
|
|
|
+ if let textView = textView {
|
|
|
+ textView.translatesAutoresizingMaskIntoConstraints = false
|
|
|
+ NSLayoutConstraint.activate([
|
|
|
+ textView.centerXAnchor.constraint(equalTo: centerXAnchor),
|
|
|
+ textView.bottomAnchor.constraint(equalTo: markerImageView.topAnchor, constant: -spacing)
|
|
|
+ ])
|
|
|
+ }
|
|
|
|
|
|
- // 设置注释视图的大小
|
|
|
- self.frame = imageView.frame
|
|
|
+ // 设置标记视图整体尺寸
|
|
|
+ let textHeight = textView?.intrinsicContentSize.height ?? 0
|
|
|
+ let totalHeight = textView != nil ?
|
|
|
+ markerSize.height + textHeight + spacing :
|
|
|
+ markerSize.height
|
|
|
|
|
|
- // 设置注释视图的中心点偏移
|
|
|
- self.centerOffset = CGPoint(x: 0, y: -imageView.frame.height / 2)
|
|
|
+ // 宽度至少和markerImageView一样宽,高度根据是否有文本决定
|
|
|
+ NSLayoutConstraint.activate([
|
|
|
+ widthAnchor.constraint(greaterThanOrEqualTo: markerImageView.widthAnchor),
|
|
|
+ heightAnchor.constraint(equalToConstant: totalHeight)
|
|
|
+ ])
|
|
|
+
|
|
|
+ // 更新偏移量
|
|
|
+ updateCenterOffset()
|
|
|
+ }
|
|
|
+
|
|
|
+ // MARK: - 更新视图
|
|
|
+
|
|
|
+ override func layoutSubviews() {
|
|
|
+ super.layoutSubviews()
|
|
|
+ updateCenterOffset()
|
|
|
+ }
|
|
|
+
|
|
|
+ private func updateCenterOffset() {
|
|
|
+ let markerSize = marker?.markerType.size ?? CGSize(width: 30, height: 30)
|
|
|
+
|
|
|
+ if let textView = textView {
|
|
|
+ let textHeight = textView.frame.height
|
|
|
+ let totalHeight = markerSize.height + textHeight + spacing
|
|
|
+
|
|
|
+ // 有文本时,调整偏移让图片底部对准坐标点
|
|
|
+ centerOffset = CGPoint(x: 0, y: -(totalHeight - markerSize.height)/2)
|
|
|
+ } else {
|
|
|
+ // 没有文本时,仅需要将图片底部对准坐标点
|
|
|
+ centerOffset = CGPoint(x: 0, y: -markerSize.height/2)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
override func prepareForDisplay() {
|
|
|
super.prepareForDisplay()
|
|
|
-
|
|
|
- // 确保图像是最新的
|
|
|
updateImage()
|
|
|
}
|
|
|
|
|
|
private func updateImage() {
|
|
|
- let oldImage = imageView.image
|
|
|
- imageView.image = uiImage
|
|
|
-
|
|
|
- // 如果图像发生变化或为空,重新设置图像视图
|
|
|
- if imageView.image == nil || oldImage != imageView.image {
|
|
|
- setupImageView()
|
|
|
- }
|
|
|
+ markerImageView.isSelected = annotationSelected
|
|
|
}
|
|
|
|
|
|
override func setSelected(_ selected: Bool, animated: Bool) {
|
|
|
super.setSelected(selected, animated: animated)
|
|
|
- if selected {
|
|
|
- self.marker?.isSelected = true
|
|
|
- } else {
|
|
|
- self.marker?.isSelected = false
|
|
|
- }
|
|
|
-
|
|
|
- // 更新图像以反映选中状态
|
|
|
+ marker?.isSelected = selected
|
|
|
updateImage()
|
|
|
}
|
|
|
-}
|
|
|
+}
|