@@ -13,15 +13,33 @@ import MapKit
1313
1414import TripKit
1515
16+ protocol TKUIVehicleAnnotation : MKAnnotation {
17+ var serviceColor : TKColor ? { get }
18+ var icon : String ? { get }
19+ var serviceNumber : String ? { get }
20+ var bearing : NSNumber ? { get }
21+ var componentsData : Data ? { get }
22+ }
23+
24+ extension TKUIVehicleAnnotation {
25+ var serviceColor : TKColor ? { nil }
26+ var icon : String ? { nil }
27+ var serviceNumber : String ? { nil }
28+ var bearing : NSNumber ? { nil }
29+ var componentsData : Data ? { nil }
30+ }
31+
32+ extension Vehicle : TKUIVehicleAnnotation { }
33+
1634class TKUIVehicleAnnotationView : TKUIPulsingAnnotationView {
1735
1836 private weak var vehicleShape : TKUIVehicleView ?
1937 private weak var vehicleImageView : UIImageView ?
2038 private weak var label : UILabel !
2139 private weak var wrapper : UIView !
2240
23- private let vehicleWidth = CGFloat ( 30 )
24- private let vehicleHeight = CGFloat ( 15 )
41+ private let vehicleWidth = CGFloat ( 38 )
42+ private let vehicleHeight = CGFloat ( 21 )
2543
2644 private let disposeBag = DisposeBag ( )
2745
@@ -66,11 +84,11 @@ class TKUIVehicleAnnotationView: TKUIPulsingAnnotationView {
6684 }
6785
6886 guard
69- let vehicle = annotation as? Vehicle else {
87+ let vehicle = annotation as? TKUIVehicleAnnotation else {
7088 return // happens on getting removed.
7189 }
7290
73- calloutOffset = CGPoint ( x: 0 , y: 10 )
91+ calloutOffset = CGPoint ( x: 0 , y: vehicleHeight / 2 )
7492 frame = CGRect ( x: 0 , y: 0 , width: 44 , height: 44 )
7593 backgroundColor = UIColor . clear
7694 isOpaque = false
@@ -95,6 +113,11 @@ class TKUIVehicleAnnotationView: TKUIPulsingAnnotationView {
95113 self . vehicleImageView = vehicleImageView
96114 } else {
97115 let vehicleShape = TKUIVehicleView ( frame: vehicleRect, color: serviceColor)
116+ vehicleShape. layer. shadowColor = UIColor . black. cgColor
117+ vehicleShape. layer. shadowOpacity = 0.25
118+ vehicleShape. layer. shadowRadius = 4
119+ vehicleShape. layer. shadowOffset = CGSize ( width: 0 , height: 2 )
120+ vehicleShape. layer. masksToBounds = false
98121 vehicleView = vehicleShape
99122 self . vehicleShape = vehicleShape
100123 }
@@ -111,7 +134,7 @@ class TKUIVehicleAnnotationView: TKUIPulsingAnnotationView {
111134 label. isOpaque = false
112135 label. textAlignment = . center
113136 label. textColor = textColorForBackgroundColor ( serviceColor)
114- label. font = TKStyleManager . customFont ( forTextStyle: . caption2)
137+ label. font = TKStyleManager . semiboldCustomFont ( forTextStyle: . caption2)
115138 label. adjustsFontSizeToFitWidth = true
116139 label. minimumScaleFactor = 0.75
117140 wrapper. addSubview ( label)
@@ -129,12 +152,13 @@ class TKUIVehicleAnnotationView: TKUIPulsingAnnotationView {
129152 observe ( vehicle)
130153 }
131154
132- private func observe( _ vehicle: Vehicle ) {
155+ private func observe( _ vehicle: TKUIVehicleAnnotation ) {
156+ guard let tkVehicle = vehicle as? Vehicle else { return }
133157
134158 // Vehicle color needs to change following real-time update.
135- vehicle . rx. observeWeakly ( Data . self, " componentsData " )
159+ tkVehicle . rx. observeWeakly ( Data . self, " componentsData " )
136160 . compactMap { data in
137- guard let data = data else { return nil }
161+ guard let data else { return nil }
138162 let components = Vehicle . components ( from: data)
139163 return TKAPI . VehicleOccupancy. average ( in: components) ? . 0 . color
140164 }
@@ -182,3 +206,23 @@ class TKUIVehicleAnnotationView: TKUIPulsingAnnotationView {
182206 return textColor
183207 }
184208}
209+
210+ #if DEBUG
211+ class PreviewVehicle : NSObject , TKUIVehicleAnnotation {
212+ var coordinate : CLLocationCoordinate2D = . invalid
213+ var serviceNumber : String ?
214+
215+ init ( serviceNumber: String ? = nil ) {
216+ self . serviceNumber = serviceNumber
217+ }
218+ }
219+
220+ @available ( iOS 17 . 0 , * )
221+ #Preview {
222+ let wrapper = UIView ( frame: . init( x: 0 , y: 0 , width: 300 , height: 600 ) )
223+ let vehicleView = TKUIVehicleAnnotationView ( with: PreviewVehicle ( serviceNumber: " 311 " ) , reuseIdentifier: " " )
224+ vehicleView. frame = . init( x: 50 , y: 100 , width: 50 , height: 50 )
225+ wrapper. addSubview ( vehicleView)
226+ return wrapper
227+ }
228+ #endif
0 commit comments