@@ -182,6 +182,8 @@ class Meter : NSObject, ObservableObject, Identifiable {
|
||
| 182 | 182 |
} |
| 183 | 183 |
} |
| 184 | 184 |
|
| 185 |
+ var preferredTabIdentifier: String = "home" |
|
| 186 |
+ |
|
| 185 | 187 |
@Published private(set) var lastConnectedAt: Date? |
| 186 | 188 |
|
| 187 | 189 |
var color : Color {
|
@@ -71,7 +71,7 @@ struct MeterView: View {
|
||
| 71 | 71 |
) |
| 72 | 72 |
} |
| 73 | 73 |
|
| 74 |
- private enum MeterTab: Hashable {
|
|
| 74 |
+ private enum MeterTab: String, Hashable {
|
|
| 75 | 75 |
case home |
| 76 | 76 |
case live |
| 77 | 77 |
case chart |
@@ -163,6 +163,9 @@ struct MeterView: View {
|
||
| 163 | 163 |
navBarRSSI = newRSSI |
| 164 | 164 |
} |
| 165 | 165 |
} |
| 166 |
+ .onChange(of: selectedMeterTab) { newTab in
|
|
| 167 |
+ meter.preferredTabIdentifier = newTab.rawValue |
|
| 168 |
+ } |
|
| 166 | 169 |
} |
| 167 | 170 |
|
| 168 | 171 |
// MARK: - Custom navigation header for Designed-for-iPad on Mac |
@@ -232,18 +235,15 @@ struct MeterView: View {
|
||
| 232 | 235 |
landscapeSegmentedContent(size: size) |
| 233 | 236 |
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) |
| 234 | 237 |
.padding(.top, landscapeContentTopPadding(for: tabBarStyle)) |
| 235 |
- .id(selectedMeterTab) |
|
| 238 |
+ .id(displayedMeterTab) |
|
| 236 | 239 |
.transition(.opacity.combined(with: .move(edge: .trailing))) |
| 237 | 240 |
|
| 238 | 241 |
segmentedTabBar(style: tabBarStyle, showsConnectionAction: !Self.isMacIPadApp) |
| 239 | 242 |
} |
| 240 |
- .animation(.easeInOut(duration: 0.22), value: selectedMeterTab) |
|
| 243 |
+ .animation(.easeInOut(duration: 0.22), value: displayedMeterTab) |
|
| 241 | 244 |
.animation(.easeInOut(duration: 0.22), value: availableMeterTabs) |
| 242 | 245 |
.onAppear {
|
| 243 |
- normalizeSelectedTab() |
|
| 244 |
- } |
|
| 245 |
- .onChange(of: availableMeterTabs) { _ in
|
|
| 246 |
- normalizeSelectedTab() |
|
| 246 |
+ restoreSelectedTab() |
|
| 247 | 247 |
} |
| 248 | 248 |
.onPreferenceChange(MeterTabBarHeightPreferenceKey.self) { height in
|
| 249 | 249 |
if height > 0 {
|
@@ -258,16 +258,13 @@ struct MeterView: View {
|
||
| 258 | 258 |
|
| 259 | 259 |
landscapeSegmentedContent(size: size) |
| 260 | 260 |
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) |
| 261 |
- .id(selectedMeterTab) |
|
| 261 |
+ .id(displayedMeterTab) |
|
| 262 | 262 |
.transition(.opacity.combined(with: .move(edge: .trailing))) |
| 263 | 263 |
} |
| 264 |
- .animation(.easeInOut(duration: 0.22), value: selectedMeterTab) |
|
| 264 |
+ .animation(.easeInOut(duration: 0.22), value: displayedMeterTab) |
|
| 265 | 265 |
.animation(.easeInOut(duration: 0.22), value: availableMeterTabs) |
| 266 | 266 |
.onAppear {
|
| 267 |
- normalizeSelectedTab() |
|
| 268 |
- } |
|
| 269 |
- .onChange(of: availableMeterTabs) { _ in
|
|
| 270 |
- normalizeSelectedTab() |
|
| 267 |
+ restoreSelectedTab() |
|
| 271 | 268 |
} |
| 272 | 269 |
} |
| 273 | 270 |
|
@@ -277,16 +274,13 @@ struct MeterView: View {
|
||
| 277 | 274 |
|
| 278 | 275 |
portraitSegmentedContent(size: size) |
| 279 | 276 |
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) |
| 280 |
- .id(selectedMeterTab) |
|
| 277 |
+ .id(displayedMeterTab) |
|
| 281 | 278 |
.transition(.opacity.combined(with: .move(edge: .trailing))) |
| 282 | 279 |
} |
| 283 |
- .animation(.easeInOut(duration: 0.22), value: selectedMeterTab) |
|
| 280 |
+ .animation(.easeInOut(duration: 0.22), value: displayedMeterTab) |
|
| 284 | 281 |
.animation(.easeInOut(duration: 0.22), value: availableMeterTabs) |
| 285 | 282 |
.onAppear {
|
| 286 |
- normalizeSelectedTab() |
|
| 287 |
- } |
|
| 288 |
- .onChange(of: availableMeterTabs) { _ in
|
|
| 289 |
- normalizeSelectedTab() |
|
| 283 |
+ restoreSelectedTab() |
|
| 290 | 284 |
} |
| 291 | 285 |
} |
| 292 | 286 |
|
@@ -299,7 +293,7 @@ struct MeterView: View {
|
||
| 299 | 293 |
|
| 300 | 294 |
HStack(spacing: 8) {
|
| 301 | 295 |
ForEach(availableMeterTabs, id: \.self) { tab in
|
| 302 |
- let isSelected = selectedMeterTab == tab |
|
| 296 |
+ let isSelected = displayedMeterTab == tab |
|
| 303 | 297 |
|
| 304 | 298 |
Button {
|
| 305 | 299 |
withAnimation(.easeInOut(duration: 0.2)) {
|
@@ -420,21 +414,13 @@ struct MeterView: View {
|
||
| 420 | 414 |
|
| 421 | 415 |
@ViewBuilder |
| 422 | 416 |
private func landscapeSegmentedContent(size: CGSize) -> some View {
|
| 423 |
- switch selectedMeterTab {
|
|
| 417 |
+ switch displayedMeterTab {
|
|
| 424 | 418 |
case .home: |
| 425 | 419 |
MeterHomeTabView(size: size, isLandscape: true) |
| 426 | 420 |
case .live: |
| 427 |
- if meter.operationalState == .dataIsAvailable {
|
|
| 428 |
- MeterLiveTabView(size: size, isLandscape: true) |
|
| 429 |
- } else {
|
|
| 430 |
- MeterHomeTabView(size: size, isLandscape: true) |
|
| 431 |
- } |
|
| 421 |
+ MeterLiveTabView(size: size, isLandscape: true) |
|
| 432 | 422 |
case .chart: |
| 433 |
- if meter.measurements.power.context.isValid && meter.operationalState == .dataIsAvailable {
|
|
| 434 |
- MeterChartTabView(size: size, isLandscape: true) |
|
| 435 |
- } else {
|
|
| 436 |
- MeterHomeTabView(size: size, isLandscape: true) |
|
| 437 |
- } |
|
| 423 |
+ MeterChartTabView(size: size, isLandscape: true) |
|
| 438 | 424 |
case .settings: |
| 439 | 425 |
MeterSettingsTabView(isMacIPadApp: Self.isMacIPadApp) {
|
| 440 | 426 |
withAnimation(.easeInOut(duration: 0.22)) {
|
@@ -446,21 +432,13 @@ struct MeterView: View {
|
||
| 446 | 432 |
|
| 447 | 433 |
@ViewBuilder |
| 448 | 434 |
private func portraitSegmentedContent(size: CGSize) -> some View {
|
| 449 |
- switch selectedMeterTab {
|
|
| 435 |
+ switch displayedMeterTab {
|
|
| 450 | 436 |
case .home: |
| 451 | 437 |
MeterHomeTabView(size: size, isLandscape: false) |
| 452 | 438 |
case .live: |
| 453 |
- if meter.operationalState == .dataIsAvailable {
|
|
| 454 |
- MeterLiveTabView(size: size, isLandscape: false) |
|
| 455 |
- } else {
|
|
| 456 |
- MeterHomeTabView(size: size, isLandscape: false) |
|
| 457 |
- } |
|
| 439 |
+ MeterLiveTabView(size: size, isLandscape: false) |
|
| 458 | 440 |
case .chart: |
| 459 |
- if meter.measurements.power.context.isValid && meter.operationalState == .dataIsAvailable {
|
|
| 460 |
- MeterChartTabView(size: size, isLandscape: false) |
|
| 461 |
- } else {
|
|
| 462 |
- MeterHomeTabView(size: size, isLandscape: false) |
|
| 463 |
- } |
|
| 441 |
+ MeterChartTabView(size: size, isLandscape: false) |
|
| 464 | 442 |
case .settings: |
| 465 | 443 |
MeterSettingsTabView(isMacIPadApp: Self.isMacIPadApp) {
|
| 466 | 444 |
withAnimation(.easeInOut(duration: 0.22)) {
|
@@ -486,13 +464,21 @@ struct MeterView: View {
|
||
| 486 | 464 |
return tabs |
| 487 | 465 |
} |
| 488 | 466 |
|
| 489 |
- private func normalizeSelectedTab() {
|
|
| 490 |
- guard availableMeterTabs.contains(selectedMeterTab) else {
|
|
| 491 |
- withAnimation(.easeInOut(duration: 0.22)) {
|
|
| 492 |
- selectedMeterTab = .home |
|
| 493 |
- } |
|
| 467 |
+ private var displayedMeterTab: MeterTab {
|
|
| 468 |
+ if availableMeterTabs.contains(selectedMeterTab) {
|
|
| 469 |
+ return selectedMeterTab |
|
| 470 |
+ } |
|
| 471 |
+ return .home |
|
| 472 |
+ } |
|
| 473 |
+ |
|
| 474 |
+ private func restoreSelectedTab() {
|
|
| 475 |
+ guard let restoredTab = MeterTab(rawValue: meter.preferredTabIdentifier) else {
|
|
| 476 |
+ meter.preferredTabIdentifier = MeterTab.home.rawValue |
|
| 477 |
+ selectedMeterTab = .home |
|
| 494 | 478 |
return |
| 495 | 479 |
} |
| 480 |
+ |
|
| 481 |
+ selectedMeterTab = restoredTab |
|
| 496 | 482 |
} |
| 497 | 483 |
|
| 498 | 484 |
private var meterBackground: some View {
|