From 2f19388cbf37f6f0d745297123b5b2b0fc8b9ea6 Mon Sep 17 00:00:00 2001 From: Laurent Date: Thu, 16 Feb 2023 10:21:47 +0100 Subject: [PATCH] size classes --- LeCountdown.xcodeproj/project.pbxproj | 4 ++ LeCountdown/CountdownScheduler.swift | 1 - LeCountdown/LeCountdownApp.swift | 63 ++++++-------------- LeCountdown/Views/HomeView.swift | 86 +++++++++++++++++++++++++++ LeCountdown/Views/PresetsView.swift | 21 ++++++- 5 files changed, 127 insertions(+), 48 deletions(-) create mode 100644 LeCountdown/Views/HomeView.swift diff --git a/LeCountdown.xcodeproj/project.pbxproj b/LeCountdown.xcodeproj/project.pbxproj index 0221b8e..40a7f2b 100644 --- a/LeCountdown.xcodeproj/project.pbxproj +++ b/LeCountdown.xcodeproj/project.pbxproj @@ -107,6 +107,7 @@ C4BA2B1F299BE6A100CB4FBA /* Countdown+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4BA2B0E299BE61E00CB4FBA /* Countdown+CoreDataProperties.swift */; }; C4BA2B22299BE82E00CB4FBA /* AbstractSoundTimer+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4BA2AEF2996A11900CB4FBA /* AbstractSoundTimer+CoreDataProperties.swift */; }; C4BA2B23299BE82E00CB4FBA /* AbstractSoundTimer+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4BA2AEF2996A11900CB4FBA /* AbstractSoundTimer+CoreDataProperties.swift */; }; + C4BA2B25299D35C100CB4FBA /* HomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4BA2B24299D35C100CB4FBA /* HomeView.swift */; }; C4F8B1532987FE6F005C86A5 /* LaunchWidgetLiveActivity.swift in Sources */ = {isa = PBXBuildFile; fileRef = C438C7D72981216200BF3EF9 /* LaunchWidgetLiveActivity.swift */; }; C4F8B15729891271005C86A5 /* Conductor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4F8B15629891271005C86A5 /* Conductor.swift */; }; C4F8B15929891528005C86A5 /* forest_stream.mp3 in Resources */ = {isa = PBXBuildFile; fileRef = C4F8B15829891528005C86A5 /* forest_stream.mp3 */; }; @@ -287,6 +288,7 @@ C4BA2B0C299BE61E00CB4FBA /* IntervalGroup+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "IntervalGroup+CoreDataClass.swift"; sourceTree = ""; }; C4BA2B0D299BE61E00CB4FBA /* IntervalGroup+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "IntervalGroup+CoreDataProperties.swift"; sourceTree = ""; }; C4BA2B0E299BE61E00CB4FBA /* Countdown+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Countdown+CoreDataProperties.swift"; sourceTree = ""; }; + C4BA2B24299D35C100CB4FBA /* HomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeView.swift; sourceTree = ""; }; C4F8B15629891271005C86A5 /* Conductor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Conductor.swift; sourceTree = ""; }; C4F8B15829891528005C86A5 /* forest_stream.mp3 */ = {isa = PBXFileReference; lastKnownFileType = audio.mp3; path = forest_stream.mp3; sourceTree = ""; }; C4F8B15E298961A7005C86A5 /* ReorderableForEach.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReorderableForEach.swift; sourceTree = ""; }; @@ -508,6 +510,7 @@ C4F8B1D3298BF686005C86A5 /* Components */, C4060DC1297AE73B003FAB80 /* ContentView.swift */, C4F8B1CF298BF2E2005C86A5 /* DialView.swift */, + C4BA2B24299D35C100CB4FBA /* HomeView.swift */, C498E59E298D4DEA00E90DE0 /* LiveTimerListView.swift */, C4BA2B03299A42EF00CB4FBA /* NewDataView.swift */, C4BA2B05299A8F8D00CB4FBA /* PresetsView.swift */, @@ -848,6 +851,7 @@ C4BA2B12299BE61E00CB4FBA /* IntervalGroup+CoreDataProperties.swift in Sources */, C4BA2AF32996A11900CB4FBA /* AbstractSoundTimer+CoreDataProperties.swift in Sources */, C4742B59298411E800D5D950 /* CountdownFormView.swift in Sources */, + C4BA2B25299D35C100CB4FBA /* HomeView.swift in Sources */, C4BA2AF12996A11900CB4FBA /* CustomSound+CoreDataClass.swift in Sources */, C4060DC2297AE73B003FAB80 /* ContentView.swift in Sources */, C438C7C12980228B00BF3EF9 /* CountdownScheduler.swift in Sources */, diff --git a/LeCountdown/CountdownScheduler.swift b/LeCountdown/CountdownScheduler.swift index 5d9a803..88735cf 100644 --- a/LeCountdown/CountdownScheduler.swift +++ b/LeCountdown/CountdownScheduler.swift @@ -48,7 +48,6 @@ class CountdownScheduler { // content.sound = UNNotificationSound(named: UNNotificationSoundName(rawValue: sound)) content.sound = UNNotificationSound.criticalSoundNamed(UNNotificationSoundName(rawValue: sound), withAudioVolume: 1.0) - content.interruptionLevel = .critical content.relevanceScore = 1.0 diff --git a/LeCountdown/LeCountdownApp.swift b/LeCountdown/LeCountdownApp.swift index 78ebdbf..aa94556 100644 --- a/LeCountdown/LeCountdownApp.swift +++ b/LeCountdown/LeCountdownApp.swift @@ -18,8 +18,6 @@ enum BGTaskIdentifier : String { struct LeCountdownApp: App { let persistenceController = PersistenceController.shared - - @State private var tabSelection: Int = 1 @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate @@ -32,37 +30,35 @@ struct LeCountdownApp: App { self._registerBackgroundRefreshes() } + #if os(iOS) + @Environment(\.horizontalSizeClass) private var horizontalSizeClass + #endif + var body: some Scene { + WindowGroup { - - NavigationStack { - TabView(selection: $tabSelection) { - PresetsView(tabSelection: $tabSelection) + Group { + #if os(iOS) + if horizontalSizeClass == .compact { + CompactHomeView() .environment(\.managedObjectContext, persistenceController.container.viewContext) - .tabItem { Label("Presets", systemImage: "globe") } - .tag(0) - ContentView() + } else { + RegularHomeView() .environment(\.managedObjectContext, persistenceController.container.viewContext) - .environmentObject(Conductor.maestro) - .tabItem { Label("Home", systemImage: "clock.fill") } - .tag(1) - RecordsView().environment(\.managedObjectContext, persistenceController.container.viewContext) - .tabItem { Label("Stats", systemImage: "chart.bar.fill") } - .tag(2) } - }.tabViewStyle(.page) + #else + RegularHomeView() + .environment(\.managedObjectContext, persistenceController.container.viewContext) + #endif + } .onReceive(NotificationCenter.default.publisher(for: UIApplication.willEnterForegroundNotification)) { _ in self._willEnterForegroundNotification() } .onAppear { self._onAppear() } - .onOpenURL { url in - print("open URL = \(url)") - self._performActionIfPossible(url: url) - } - } + } fileprivate func _willEnterForegroundNotification() { @@ -106,29 +102,4 @@ struct LeCountdownApp: App { } - /// Show the appropriate tab - /// Actions are launched from the ContentView - fileprivate func _performActionIfPossible(url: URL) { - - let context = persistenceController.container.viewContext - let urlString = url.absoluteString - if let timer = context.object(stringId: urlString) as? AbstractTimer { - - switch timer { - case is Countdown: - self.tabSelection = 1 - case is Stopwatch: - self.tabSelection = 2 - case is Alarm: - self.tabSelection = 3 - default: - print("url not managed, object is \(timer)") - break - } - } else { - print("url not managed: \(url)") - } - - } - } diff --git a/LeCountdown/Views/HomeView.swift b/LeCountdown/Views/HomeView.swift new file mode 100644 index 0000000..3e15db6 --- /dev/null +++ b/LeCountdown/Views/HomeView.swift @@ -0,0 +1,86 @@ +// +// HomeView.swift +// LeCountdown +// +// Created by Laurent Morvillier on 15/02/2023. +// + +import SwiftUI + +struct CompactHomeView: View { + + @Environment(\.managedObjectContext) private var viewContext + + @State private var tabSelection: Int = 1 + + var body: some View { + + NavigationStack { + TabView(selection: $tabSelection) { + PresetsView(tabSelection: $tabSelection) + .environment(\.managedObjectContext, viewContext) + .tabItem { Label("Presets", systemImage: "globe") } + .tag(0) + ContentView() + .environment(\.managedObjectContext, viewContext) + .environmentObject(Conductor.maestro) + .tabItem { Label("Home", systemImage: "clock.fill") } + .tag(1) + RecordsView() + .environment(\.managedObjectContext, viewContext) + .tabItem { Label("Stats", systemImage: "chart.bar.fill") } + .tag(2) + } + .tabViewStyle(.page) + .onOpenURL { _ in + self.tabSelection = 1 + } + } + } + +} + +struct RegularHomeView: View { + + @Environment(\.managedObjectContext) private var viewContext + + @State private var tabSelection: Int = 1 + + var body: some View { + + NavigationStack { + TabView(selection: $tabSelection) { + PresetsView(tabSelection: $tabSelection) + .environment(\.managedObjectContext, viewContext) + .tabItem { Label("Presets", systemImage: "globe") } + .tag(0) + ContentView() + .environment(\.managedObjectContext, viewContext) + .environmentObject(Conductor.maestro) + .tabItem { Label("Home", systemImage: "clock.fill") } + .tag(1) + RecordsView() + .environment(\.managedObjectContext, viewContext) + .tabItem { Label("Stats", systemImage: "chart.bar.fill") } + .tag(2) + } + } + .tabViewStyle(.page) + .onOpenURL { _ in + self.tabSelection = 1 + } + } + +} + +struct CompactHomeView_Previews: PreviewProvider { + static var previews: some View { + CompactHomeView().previewDevice(PreviewDevice(rawValue: "iPhone 12 Pro")) + } +} + +struct RegularHomeView_Previews: PreviewProvider { + static var previews: some View { + RegularHomeView().previewDevice(PreviewDevice(rawValue: "iPad Pro (11-inch)")) + } +} diff --git a/LeCountdown/Views/PresetsView.swift b/LeCountdown/Views/PresetsView.swift index 33a9ee4..e542a35 100644 --- a/LeCountdown/Views/PresetsView.swift +++ b/LeCountdown/Views/PresetsView.swift @@ -144,6 +144,9 @@ class PresetModel : ObservableObject { struct PresetsView: View { @Environment(\.managedObjectContext) private var viewContext + #if os(iOS) + @Environment(\.horizontalSizeClass) private var horizontalSizeClass + #endif @StateObject var model: PresetModel = PresetModel() @@ -156,6 +159,22 @@ struct PresetsView: View { GridItem(spacing: 10.0), ] + fileprivate func _columnCount() -> Int { + #if os(iOS) + if horizontalSizeClass == .compact { + return 2 + } else { + return 3 + } + #else + return 3 + #endif + } + + fileprivate func _columns() -> [GridItem] { + return (0..