1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
|
@objc(MWMRoutePreviewStatus)
final class RoutePreviewStatus: SolidTouchView {
@IBOutlet private weak var errorBox: UIView!
@IBOutlet private weak var resultsBox: UIView!
@IBOutlet private weak var heightBox: UIView!
@IBOutlet private weak var manageRouteBox: UIView! {
didSet {
iPhoneSpecific {
manageRouteBox.backgroundColor = UIColor.blackOpaque()
}
}
}
@IBOutlet private weak var taxiBox: UIView!
@IBOutlet private weak var errorLabel: UILabel!
@IBOutlet private weak var resultLabel: UILabel!
@IBOutlet private weak var arriveLabel: UILabel?
@IBOutlet private weak var heightProfileImage: UIImageView!
@IBOutlet private weak var heightProfileElevationHeight: UILabel?
@IBOutlet private weak var manageRouteButtonRegular: UIButton! {
didSet {
configManageRouteButton(manageRouteButtonRegular)
}
}
@IBOutlet private weak var manageRouteButtonCompact: UIButton? {
didSet {
configManageRouteButton(manageRouteButtonCompact!)
}
}
@IBOutlet private var errorBoxBottom: NSLayoutConstraint!
@IBOutlet private var resultsBoxBottom: NSLayoutConstraint!
@IBOutlet private var heightBoxBottom: NSLayoutConstraint!
@IBOutlet private var taxiBoxBottom: NSLayoutConstraint!
@IBOutlet private var manageRouteBoxBottom: NSLayoutConstraint!
@IBOutlet private var heightBoxBottomManageRouteBoxTop: NSLayoutConstraint!
private var hiddenConstraint: NSLayoutConstraint!
weak var ownerView: UIView!
weak var navigationInfo: MWMNavigationDashboardEntity?
var elevation: NSAttributedString? {
didSet {
guard let elevation = elevation else { return }
alternative(iPhone: { self.updateResultsLabel() },
iPad: { self.heightProfileElevationHeight?.attributedText = elevation })()
}
}
var isVisible = false {
didSet {
alternative(iPhone: {
guard self.isVisible != oldValue else { return }
if self.isVisible {
self.addView()
}
DispatchQueue.main.async {
guard let sv = self.superview else { return }
sv.setNeedsLayout()
self.hiddenConstraint.isActive = !self.isVisible
UIView.animate(withDuration: kDefaultAnimationDuration,
animations: { sv.layoutIfNeeded() },
completion: { _ in
if !self.isVisible {
self.removeFromSuperview()
}
})
}
},
iPad: { self.isHidden = !self.isVisible })()
}
}
private func addView() {
guard superview != ownerView else { return }
ownerView.addSubview(self)
NSLayoutConstraint(item: self, attribute: .left, relatedBy: .equal, toItem: ownerView, attribute: .left, multiplier: 1, constant: 0).isActive = true
NSLayoutConstraint(item: self, attribute: .right, relatedBy: .equal, toItem: ownerView, attribute: .right, multiplier: 1, constant: 0).isActive = true
hiddenConstraint = NSLayoutConstraint(item: self, attribute: .top, relatedBy: .equal, toItem: ownerView, attribute: .bottom, multiplier: 1, constant: 0)
hiddenConstraint.priority = UILayoutPriorityDefaultHigh
hiddenConstraint.isActive = true
let visibleConstraint = NSLayoutConstraint(item: self, attribute: .bottom, relatedBy: .equal, toItem: ownerView, attribute: .bottom, multiplier: 1, constant: 0)
visibleConstraint.priority = UILayoutPriorityDefaultLow
visibleConstraint.isActive = true
}
private func updateHeight() {
DispatchQueue.main.async {
self.setNeedsLayout()
self.errorBoxBottom.isActive = !self.errorBox.isHidden
self.resultsBoxBottom.isActive = !self.resultsBox.isHidden
self.heightBoxBottom.isActive = !self.heightBox.isHidden
self.heightBoxBottomManageRouteBoxTop.isActive = !self.heightBox.isHidden
self.taxiBoxBottom.isActive = !self.taxiBox.isHidden
self.manageRouteBoxBottom.isActive = !self.manageRouteBox.isHidden
UIView.animate(withDuration: kDefaultAnimationDuration) { self.layoutIfNeeded() }
}
}
private func configManageRouteButton(_ button: UIButton) {
button.titleLabel?.font = UIFont.medium14()
button.setTitle(L("planning_route_manage_route"), for: .normal)
button.tintColor = UIColor.blackSecondaryText()
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
updateManageRouteVisibility()
updateHeight()
}
private func updateManageRouteVisibility() {
let isCompact = traitCollection.verticalSizeClass == .compact
manageRouteBox.isHidden = isCompact || resultsBox.isHidden
manageRouteButtonCompact?.isHidden = !isCompact
}
func stateHidden() {
isVisible = false
}
func statePrepare() {
isVisible = false
}
func stateError(message: String) {
isVisible = true
errorBox.isHidden = false
resultsBox.isHidden = true
heightBox.isHidden = true
taxiBox.isHidden = true
manageRouteBox.isHidden = true
errorLabel.text = message
updateHeight()
}
func stateReady() {
isVisible = true
errorBox.isHidden = true
if MWMRouter.isTaxi() {
taxiBox.isHidden = false
resultsBox.isHidden = true
heightBox.isHidden = true
} else {
taxiBox.isHidden = true
resultsBox.isHidden = false
self.elevation = nil
if MWMRouter.hasRouteAltitude() {
heightBox.isHidden = false
MWMRouter.routeAltitudeImage(for: heightProfileImage.frame.size,
completion: { image, elevation in
self.heightProfileImage.image = image
if let elevation = elevation {
let attributes: [String: Any] = [
NSForegroundColorAttributeName: UIColor.linkBlue(),
NSFontAttributeName: UIFont.medium14(),
]
self.elevation = NSAttributedString(string: "▲▼ \(elevation)", attributes: attributes)
}
})
} else {
heightBox.isHidden = true
}
}
updateManageRouteVisibility()
updateHeight()
}
func stateNavigation() {
isVisible = false
}
private func updateResultsLabel() {
guard let info = navigationInfo else { return }
resultLabel.attributedText = alternative(iPhone: {
let result = info.estimate.mutableCopy() as! NSMutableAttributedString
if let elevation = self.elevation {
result.append(info.estimateDot)
result.append(elevation)
}
return result.copy() as? NSAttributedString
},
iPad: { info.estimate })()
}
func onNavigationInfoUpdated(_ info: MWMNavigationDashboardEntity) {
navigationInfo = info
updateResultsLabel()
arriveLabel?.text = String(coreFormat: L("routing_arrive"), arguments: [info.arrival])
}
override var sideButtonsAreaAffectDirections: MWMAvailableAreaAffectDirections {
return alternative(iPhone: .bottom, iPad: [])
}
override var visibleAreaAffectDirections: MWMAvailableAreaAffectDirections {
return alternative(iPhone: .bottom, iPad: [])
}
}
|