|
Bogdan Timofte
authored
a month ago
|
1
|
# Navigation Style Decisions
|
|
|
2
|
|
|
|
3
|
## Obiectiv
|
|
|
4
|
|
|
|
5
|
Navigația aplicației folosește stilul SwiftUI implicit, cu un singur set de modificatori aplicat consistent în toate view-urile. Nu există logică condiționată per platformă pentru controlul navigației.
|
|
|
6
|
|
|
|
7
|
## Deviații de la comportamentul SwiftUI implicit
|
|
|
8
|
|
|
|
9
|
### 1. Titlu inline (`.navigationBarTitleDisplayMode(.inline)`)
|
|
|
10
|
|
|
|
11
|
**Aplicat pe:** toate view-urile care au `.navigationTitle(...)`.
|
|
|
12
|
|
|
|
13
|
**Motivație:** Implicit, SwiftUI afișează titlul mare (`.large`) în prima fereastră a unui NavigationStack sau NavigationView. Stilul large nu se potrivește layoutului aplicației, care folosește un tab bar custom imediat sub navigation bar — titlul mare consumă spațiu vertical fără beneficiu. Stilul inline plasează titlul centrat în toolbar, aliniind aspectul pe iPhone, iPad și Mac Catalyst.
|
|
|
14
|
|
|
|
15
|
**Fișiere afectate:**
|
|
|
16
|
- `Views/Meter/MeterView.swift` — live body și offline body
|
|
|
17
|
- `Views/ChargedDevices/Details/ChargedDeviceDetailView.swift`
|
|
|
18
|
- `Views/ChargedDevices/Sessions/ChargeSessionDetailView.swift`
|
|
|
19
|
- `Views/ChargedDevices/Sessions/ChargedDeviceSessionsView.swift`
|
|
|
20
|
- `Views/Meter/Tabs/Live/ChargerStandbyPowerWizardView.swift`
|
|
|
21
|
- `Views/MeterMappingDebugView.swift`
|
|
|
22
|
- `Views/DeviceHelpView.swift`
|
|
|
23
|
- Sheets (deja aveau `.inline`): `ChargedDeviceEditorScaffoldView`, `SidebarChargedDeviceLibraryView`, și altele
|
|
|
24
|
|
|
|
25
|
### 2. Font titlu navigation bar (19pt semibold)
|
|
|
26
|
|
|
|
27
|
**Aplicat în:** `AppDelegate.configureNavigationBarAppearance()` via `UINavigationBarAppearance`.
|
|
|
28
|
|
|
|
29
|
**Motivație:** Fontul implicit al titlului inline este `.headline` (17pt semibold), perceput ca prea mic față de densitatea vizuală a conținutului. 19pt semibold oferă mai multă prezență fără a afecta spațiul disponibil, întrucât titlul rămâne pe un singur rând.
|
|
|
30
|
|
|
|
31
|
**Configurare:**
|
|
|
32
|
```swift
|
|
|
33
|
let titleFont = UIFont.systemFont(ofSize: 19, weight: .semibold)
|
|
|
34
|
let appearance = UINavigationBarAppearance()
|
|
|
35
|
appearance.configureWithDefaultBackground()
|
|
|
36
|
appearance.titleTextAttributes = [.font: titleFont]
|
|
|
37
|
UINavigationBar.appearance().standardAppearance = appearance
|
|
|
38
|
UINavigationBar.appearance().scrollEdgeAppearance = appearance
|
|
|
39
|
UINavigationBar.appearance().compactAppearance = appearance
|
|
|
40
|
```
|
|
|
41
|
|
|
|
42
|
## Ce NU s-a schimbat față de implicit
|
|
|
43
|
|
|
|
44
|
- `NavigationView` cu `.navigationViewStyle(.stack)` pe iPhone și `.navigationViewStyle(.columns)` pe iPad/Mac — arhitectural, nu cosmetic
|
|
|
45
|
- Toolbar items (`.toolbar { }`) — plasate standard pe `.navigationBarTrailing` / `.cancellationAction` / `.confirmationAction`
|
|
|
46
|
- Fundalul navigation bar — `configureWithDefaultBackground()` păstrează comportamentul implicit al sistemului (translucid/blur)
|
|
|
47
|
|
|
|
48
|
## Istoric
|
|
|
49
|
|
|
|
50
|
Anterior existau mai multe straturi de modificatori conflictuali adăugați în tentative de a obține un layout compact "Nav Control – Title – Tools" pe Mac Catalyst și iPad:
|
|
|
51
|
- `navigationBarHidden(landscape)` — ascundea bara în landscape pe Catalyst
|
|
|
52
|
- `IOSOnlyNavBar` (ViewModifier) — aplica titlu și toolbar condițional pe `!isTrueMacApp`
|
|
|
53
|
- `macNavigationHeader` și `offlineMacHeader` — headere custom inline în VStack care dublau controalele când bara de sistem era vizibilă
|
|
|
54
|
- `ToolbarItemGroup(placement: .primaryAction) {}` gol pe Catalyst — crea artefacte vizuale
|
|
|
55
|
|
|
|
56
|
Toate au fost eliminate în aprilie 2026. Soluția corectă a fost `.navigationBarTitleDisplayMode(.inline)` aplicat consistent.
|