Browse Source

fix : 提交添加有电池的显示。

“HeShaoZe” 4 months ago
parent
commit
a703d60aa4

+ 260 - 0
plugins/map_mapkit_ios/ios/Classes/MapView/Views/MapAnnotationBatteryView.swift

@@ -0,0 +1,260 @@
+//
+//  MapAnnotationBatteryView.swift
+//  map_mapkit_ios
+//
+//  Created by 诺诺诺的言 on 2025/7/18.
+//
+
+import Foundation
+import UIKit
+
+class MapAnnotationBatteryView: UIView {
+    // 电池百分比 (0-100)
+    var percentage: Int = 100 {
+        didSet {
+            percentage = min(100, max(0, percentage))
+            setNeedsDisplay()
+        }
+    }
+    
+    // 电池颜色
+    var batteryColor: UIColor = {
+        if #available(iOS 13.0, *) {
+            return .systemGreen
+        } else {
+            return UIColor(red: 0.20, green: 0.78, blue: 0.35, alpha: 1.00)
+        }
+    }() {
+        didSet {
+            setNeedsDisplay()
+        }
+    }
+    
+    // 低电量颜色 (默认低于20%显示红色)
+    var lowBatteryColor: UIColor = {
+        if #available(iOS 13.0, *) {
+            return .systemRed
+        } else {
+            return UIColor(red: 1.00, green: 0.23, blue: 0.19, alpha: 1.00)
+        }
+    }()
+    var lowBatteryThreshold: Int = 20
+    
+    // 边框颜色
+    var borderColor: UIColor = {
+        if #available(iOS 13.0, *) {
+            return .label
+        } else {
+            return .black
+        }
+    }() {
+        didSet {
+            setNeedsDisplay()
+        }
+    }
+    
+    // 边框宽度
+    var borderWidth: CGFloat = 1.0 {
+        didSet {
+            setNeedsDisplay()
+        }
+    }
+    
+    // 内容与边框的间距
+    var contentPadding: CGFloat = 1.0 {
+        didSet {
+            setNeedsDisplay()
+        }
+    }
+    
+    // 电池头与电池身体的间距
+    var headSpacing: CGFloat = 1.0 {
+        didSet {
+            setNeedsDisplay()
+        }
+    }
+    
+    // 是否显示百分比文本
+    var showPercentageText: Bool = true {
+        didSet {
+            setNeedsDisplay()
+        }
+    }
+    
+    // 文本颜色
+    var textColor: UIColor = {
+        if #available(iOS 13.0, *) {
+            return .label
+        } else {
+            return .black
+        }
+    }() {
+        didSet {
+            setNeedsDisplay()
+        }
+    }
+    
+    // 文本字体
+    var textFont: UIFont = UIFont.systemFont(ofSize: 10) {
+        didSet {
+            setNeedsDisplay()
+        }
+    }
+    
+    // 文本与电池的间距
+    var textSpacing: CGFloat = 2 {
+        didSet {
+            setNeedsDisplay()
+        }
+    }
+    
+    // 边距设置
+    var horizontalPadding: CGFloat = 6 {
+        didSet {
+            setNeedsDisplay()
+        }
+    }
+    
+    var verticalPadding: CGFloat = 4 {
+        didSet {
+            setNeedsDisplay()
+        }
+    }
+    
+    // 电池尺寸
+    var batteryWidth: CGFloat = 10 {
+        didSet {
+            setNeedsDisplay()
+        }
+    }
+    
+    var batteryHeight: CGFloat = 7 {
+        didSet {
+            setNeedsDisplay()
+        }
+    }
+    
+    private let batteryCornerRadius: CGFloat = 1.0
+    private let batteryKnobWidth: CGFloat = 2.0
+    private let batteryKnobHeight: CGFloat = 3.0
+    private let batteryKnobCornerRadius: CGFloat = 0
+    
+    override init(frame: CGRect) {
+        super.init(frame: frame)
+        backgroundColor = .clear
+    }
+    
+    required init?(coder: NSCoder) {
+        super.init(coder: coder)
+        backgroundColor = .clear
+    }
+    
+    override func draw(_ rect: CGRect) {
+        super.draw(rect)
+        
+        // 先计算文本尺寸(如果需要显示文本)
+        var textSize = CGSize.zero
+        if showPercentageText {
+            let text = "\(percentage)%"
+            let textAttributes: [NSAttributedString.Key: Any] = [
+                .font: textFont,
+                .foregroundColor: textColor
+            ]
+            textSize = text.size(withAttributes: textAttributes)
+        }
+        
+        // 计算总内容宽度
+        let totalContentWidth = batteryWidth + batteryKnobWidth + headSpacing + (showPercentageText ? (textSpacing + textSize.width) : 0)
+        
+        // 计算起始X坐标(居中)
+        let startX = (rect.width - totalContentWidth) / 2
+        
+        // 电池主体区域
+        let batteryBodyRect = CGRect(
+            x: startX,
+            y: (rect.height - batteryHeight) / 2,
+            width: batteryWidth,
+            height: batteryHeight
+        )
+        
+        // 电池头区域
+        let batteryKnobRect = CGRect(
+            x: batteryBodyRect.maxX + headSpacing,
+            y: batteryBodyRect.midY - batteryKnobHeight / 2,
+            width: batteryKnobWidth,
+            height: batteryKnobHeight
+        )
+        
+        // 绘制电池主体
+        let batteryPath = UIBezierPath(
+            roundedRect: batteryBodyRect,
+            cornerRadius: batteryCornerRadius
+        )
+        batteryPath.lineWidth = borderWidth
+        
+        // 根据电量选择颜色
+        let fillColor = percentage <= lowBatteryThreshold ? lowBatteryColor : batteryColor
+        fillColor.setStroke()
+        batteryPath.stroke()
+        
+
+        // 绘制电池头
+        let knobPath = UIBezierPath(
+            roundedRect: batteryKnobRect,
+            cornerRadius: batteryKnobCornerRadius
+        )
+        fillColor.setFill()
+        knobPath.fill()
+        
+        // 计算电量填充区域(考虑内容间距)
+        let fillWidth = (batteryWidth - borderWidth - contentPadding * 2) * CGFloat(percentage) / 100
+        let fillRect = CGRect(
+            x: batteryBodyRect.origin.x + borderWidth / 2 + contentPadding,
+            y: batteryBodyRect.origin.y + borderWidth / 2 + contentPadding,
+            width: fillWidth,
+            height: batteryHeight - borderWidth - contentPadding * 2
+        )
+        
+
+        fillColor.setFill()
+        UIBezierPath(rect: fillRect).fill()
+        
+        // 绘制百分比文本(在电池右侧)
+        if showPercentageText {
+            let text = "\(percentage)%"
+            let textAttributes: [NSAttributedString.Key: Any] = [
+                .font: textFont,
+                .foregroundColor: fillColor
+            ]
+            
+            let textRect = CGRect(
+                x: batteryKnobRect.maxX + textSpacing,
+                y: rect.midY - textSize.height / 2,
+                width: textSize.width,
+                height: textSize.height
+            )
+            
+            text.draw(in: textRect, withAttributes: textAttributes)
+        }
+    }
+
+    override var intrinsicContentSize: CGSize {
+        var textWidth: CGFloat = 0
+        if showPercentageText {
+            textWidth = "100%".size(withAttributes: [.font: textFont]).width + textSpacing
+        }
+        
+        let totalWidth = batteryWidth + batteryKnobWidth + headSpacing + textWidth
+        let totalHeight = max(batteryHeight, batteryKnobHeight)
+        
+        let sumHeight = totalHeight + verticalPadding * 2
+        self.layer.cornerRadius = sumHeight / 2.0
+        self.layer.masksToBounds = true
+        print("totalheigdfdfji---\(totalHeight + verticalPadding * 2)");
+        return CGSize(
+            width: totalWidth + horizontalPadding * 2,
+            height: totalHeight + verticalPadding * 2
+        )
+    }
+}
+

+ 52 - 9
plugins/map_mapkit_ios/ios/Classes/MapView/Views/MapAnnotationView.swift

@@ -19,6 +19,7 @@ class MapAnnotationView: MKAnnotationView {
     }
     var markerImageView: MapAnnotationMarkerImageView?
     var textView: MapAnnotationMarkerTextView?
+    var batteryView : MapAnnotationBatteryView?
     
     // spacing between text and image
     let spacing: CGFloat = 6
@@ -68,11 +69,34 @@ class MapAnnotationView: MKAnnotationView {
             addSubview(markerImageView)
         }
         
-        // 如果有标题,添加文本视图
-        if let markerName = marker.markerName, !markerName.isEmpty {
-            textView = MapAnnotationMarkerTextView(text: markerName)
-            if let textView = textView {
-                addSubview(textView)
+        ///取出判断有没有用户的电池电量
+        let tags = marker.tags
+        if let electricValue = tags?["electric"],
+           let batteryPercentage = Int(electricValue),
+           batteryPercentage > 0 {
+            batteryView = MapAnnotationBatteryView()
+            batteryView?.backgroundColor = UIColor(hex:"#FFFFFF")
+            batteryView?.frame = CGRect(x: 0, y: 0, width: 53, height: 20)
+            batteryView?.borderWidth = 1.0
+            batteryView?.contentPadding = 0.5
+            batteryView?.headSpacing = 1.0
+            batteryView?.batteryColor = UIColor(hex: "#4476FF") ?? UIColor.blue
+            batteryView?.lowBatteryColor = UIColor(hex: "#FF5249") ?? UIColor.red
+            batteryView?.lowBatteryThreshold = 30
+            batteryView?.showPercentageText = true
+            batteryView?.textFont = UIFont.boldSystemFont(ofSize: 10)
+            batteryView?.textColor = UIColor(hex: "#666666") ?? UIColor.black
+            batteryView?.layer.cornerRadius = 10
+            batteryView?.layer.masksToBounds = true
+            addSubview(batteryView ?? MapAnnotationBatteryView())
+            batteryView?.percentage = batteryPercentage
+        } else {
+            // 如果有标题,添加文本视图
+            if let markerName = marker.markerName, !markerName.isEmpty {
+                textView = MapAnnotationMarkerTextView(text: markerName)
+                if let textView = textView {
+                    addSubview(textView)
+                }
             }
         }
         
@@ -113,12 +137,26 @@ class MapAnnotationView: MKAnnotationView {
             ])
         }
         
+        ///电池电量
+        if let batteryView = batteryView {
+            batteryView.translatesAutoresizingMaskIntoConstraints = false
+            NSLayoutConstraint.activate([
+                batteryView.centerXAnchor.constraint(equalTo: centerXAnchor),
+                batteryView.bottomAnchor.constraint(equalTo: markerImageView.topAnchor, constant: -spacing)
+            ])
+        }
+
         // 设置标记视图整体尺寸
-        let textHeight = textView?.intrinsicContentSize.height ?? 0
-        let totalHeight = textView != nil ? 
-            markerSize.height + textHeight + spacing : 
+        var textHeight = textView?.intrinsicContentSize.height ?? 0
+        var totalHeight = textView != nil ?
+            markerSize.height + textHeight + spacing :
             markerSize.height
         
+        if let batteryView = batteryView  {
+            textHeight = batteryView.intrinsicContentSize.height
+            totalHeight = markerSize.height + textHeight + spacing
+        }
+        
         // 宽度至少和markerImageView一样宽,高度根据是否有文本决定
         NSLayoutConstraint.activate([
             widthAnchor.constraint(greaterThanOrEqualTo: markerImageView.widthAnchor),
@@ -145,7 +183,12 @@ class MapAnnotationView: MKAnnotationView {
             
             // 有文本时,调整偏移让图片底部对准坐标点
             centerOffset = CGPoint(x: 0, y: -(totalHeight - markerSize.height)/2)
-        } else {
+        }  else if let batteryView = batteryView {
+            let textHeight = batteryView.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)
         }