@@ -17,15 +17,19 @@ public enum MapScaleExpandDirection
1717 case rightToLeft // right to right
1818}
1919
20+ public enum MapScaleDistanceUnit
21+ {
22+ case metric
23+ case imperial // UK
24+ }
25+
2026
2127@IBDesignable
2228public final class UIMapScaleView : UIView
2329{
2430 private let SCALE_BAR_HEIGHT = CGFloat ( 4.5 )
2531 private let PADDING = CGFloat ( 1 )
26-
27- public var direction : MapScaleExpandDirection = . leftToRight
28-
32+
2933 @IBInspectable public var bodyColor : UIColor = UIColor . darkGray
3034 {
3135 didSet
@@ -41,7 +45,32 @@ public final class UIMapScaleView: UIView
4145 self . distanceLabel? . shadowColor = self . outlineColor
4246 }
4347 }
44-
48+
49+ public var direction : MapScaleExpandDirection = . leftToRight
50+ {
51+ didSet
52+ {
53+ switch self . direction
54+ {
55+ case . leftToRight:
56+ self . distanceLabel? . textAlignment = . left
57+ break
58+
59+ case . rightToLeft:
60+ self . distanceLabel? . textAlignment = . right
61+ break
62+ }
63+ }
64+ }
65+
66+ public var unit : MapScaleDistanceUnit = . metric
67+ {
68+ didSet
69+ {
70+ self . setNeedsLayout ( )
71+ }
72+ }
73+
4574 private weak var mapView : MKMapView ?
4675 private weak var distanceLabel : UILabel ?
4776 private var scaledWidth = CGFloat ( 0 )
@@ -72,9 +101,9 @@ public final class UIMapScaleView: UIView
72101
73102 let horizontalDistance = MKMetersPerMapPointAtLatitude ( mapView. centerCoordinate. latitude)
74103 let metersPerPixel = CGFloat ( mapView. visibleMapRect. size. width * horizontalDistance) / mapView. bounds. size. width
104+ let distance = self . calculateDistance ( metersPerPixel)
75105
76- let value = calculateDistance ( metersPerPixel)
77- self . scaledWidth = value. width
106+ self . scaledWidth = distance. width
78107 self . setNeedsDisplay ( )
79108
80109
@@ -92,24 +121,14 @@ public final class UIMapScaleView: UIView
92121// string: String(format: "%d %@", value.value, value.unit),
93122// attributes: attributes)
94123
95- label. text = String ( format: " %d %@ " , value . value, value . unit)
124+ label. text = String ( format: " %d %@ " , distance . value, distance . unit)
96125 label. sizeToFit ( )
97126
98- label. frame = CGRect ( x: PADDING,
99- y: self . bounds. size. height - label. bounds. size. height - SCALE_BAR_HEIGHT - ( PADDING*2) ,
100- width: self . bounds. width - ( PADDING*2) ,
101- height: label. bounds. size. height)
102-
103- switch self . direction
104- {
105- case . leftToRight:
106- self . distanceLabel? . textAlignment = . left
107- break
108-
109- case . rightToLeft:
110- self . distanceLabel? . textAlignment = . right
111- break
112- }
127+ label. frame = CGRect (
128+ x: PADDING,
129+ y: self . bounds. size. height - label. bounds. size. height - SCALE_BAR_HEIGHT - ( PADDING*2) ,
130+ width: self . bounds. width - ( PADDING*2) ,
131+ height: label. bounds. size. height)
113132 }
114133
115134 public override func draw( _ rect: CGRect )
@@ -126,7 +145,7 @@ public final class UIMapScaleView: UIView
126145
127146 switch self . direction
128147 {
129- case MapScaleExpandDirection . leftToRight:
148+ case . leftToRight:
130149 // draw outline
131150 context. setFillColor ( self . outlineColor. cgColor)
132151
@@ -154,7 +173,7 @@ public final class UIMapScaleView: UIView
154173 height: ( SCALE_BAR_HEIGHT*2) - ( PADDING*2) ) )
155174 break
156175
157- case MapScaleExpandDirection . rightToLeft:
176+ case . rightToLeft:
158177 // draw outline
159178 context. setFillColor ( self . outlineColor. cgColor)
160179
@@ -188,7 +207,11 @@ public final class UIMapScaleView: UIView
188207 {
189208 self . mapView = mapView
190209 }
191-
210+ }
211+
212+
213+ extension UIMapScaleView
214+ {
192215 private func initView( )
193216 {
194217 let label = UILabel ( frame: CGRect ( x: 0 , y: 0 , width: self . bounds. size. width, height: 20 ) )
@@ -208,19 +231,38 @@ public final class UIMapScaleView: UIView
208231 let maxScaleWidth = self . bounds. size. width - ( PADDING * 2 )
209232 let meters = maxScaleWidth * metersPerPixel
210233
211- maxValue = meters. roundDistance ( )
212- scaleWidth = maxScaleWidth * CGFloat( maxValue) / meters
213-
214- if maxValue >= 1000
234+ switch self . unit
215235 {
216- maxValue = maxValue / 1000
217- unit = " km "
218- }
219- else
220- {
221- unit = " m "
236+ case . metric:
237+ maxValue = meters. roundDistance ( )
238+ scaleWidth = maxScaleWidth * CGFloat( maxValue) / meters
239+
240+ if maxValue >= 1000
241+ {
242+ maxValue = maxValue / 1000
243+ unit = " km "
244+ }
245+ else
246+ {
247+ unit = " m "
248+ }
249+ break
250+
251+ case . imperial:
252+ unit = " ft "
253+
254+ var distance = ( meters * 3.28 )
255+ if distance >= 5280
256+ {
257+ distance /= 5280
258+ unit = " mi "
259+ }
260+
261+ maxValue = distance. roundDistance ( )
262+ scaleWidth = maxScaleWidth * CGFloat( maxValue) / distance
263+ break
222264 }
223-
265+
224266 return ( scaleWidth, maxValue, unit)
225267 }
226268}
0 commit comments