From 3832d30e0e5ba3786f0c3d374d2919e23c683cbd Mon Sep 17 00:00:00 2001 From: Brian Sakhuja Date: Sun, 7 Apr 2024 12:54:58 -0700 Subject: [PATCH] disable multitasking on ipad (issue with storyboard) Because your app supports Multitasking on iPad, you need to include the LaunchScreen.storyboard launch storyboard file in your com.bsakhuja.Epicentral bundle --- Epicentral.xcodeproj/project.pbxproj | 20 ++- .../xcdebugger/Breakpoints_v2.xcbkptlist | 137 +----------------- Epicentral/Info.plist | 12 +- Epicentral/Models/EarthquakeProperties.swift | 4 + Epicentral/States/EarthquakesState.swift | 2 +- .../EarthquakeList/EarthquakeRow.swift | 1 + .../Components/EarthquakePreviewView.swift | 17 +-- .../Views/Screens/EarthquakeDetailView.swift | 56 ++++--- .../Views/Screens/EarthquakeListView.swift | 30 ++-- .../Views/Screens/LaunchScreen.storyboard | 42 ++++-- Epicentral/Views/Screens/SettingsView.swift | 12 +- 11 files changed, 115 insertions(+), 218 deletions(-) diff --git a/Epicentral.xcodeproj/project.pbxproj b/Epicentral.xcodeproj/project.pbxproj index 199d202..492c346 100644 --- a/Epicentral.xcodeproj/project.pbxproj +++ b/Epicentral.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 060F27462BC32EC000908E15 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 060F27452BC32EC000908E15 /* LaunchScreen.storyboard */; }; 065FE1312B574D250014FD45 /* ApplicationInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 065FE1302B574D250014FD45 /* ApplicationInfo.swift */; }; 068B01A32B0DB5A90012D86C /* FloatingButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 068B01A22B0DB5A90012D86C /* FloatingButtonView.swift */; }; 068B01A82B0DB8B20012D86C /* SettingsState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 068B01A72B0DB8B20012D86C /* SettingsState.swift */; }; @@ -58,6 +59,7 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 060F27452BC32EC000908E15 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; 065FE1302B574D250014FD45 /* ApplicationInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ApplicationInfo.swift; sourceTree = ""; }; 068B01A22B0DB5A90012D86C /* FloatingButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FloatingButtonView.swift; sourceTree = ""; }; 068B01A72B0DB8B20012D86C /* SettingsState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsState.swift; sourceTree = ""; }; @@ -155,6 +157,7 @@ 06DA01622AFDBB0D0008FE49 /* SettingsView.swift */, 068B01A92B0DB9540012D86C /* EarthquakeListView.swift */, 068B01AB2B0DBAFB0012D86C /* EarthquakesMapView.swift */, + 060F27452BC32EC000908E15 /* LaunchScreen.storyboard */, ); path = Screens; sourceTree = ""; @@ -387,6 +390,7 @@ buildActionMask = 2147483647; files = ( 06EFE9E72AFABA0300351973 /* testresponse.json in Resources */, + 060F27462BC32EC000908E15 /* LaunchScreen.storyboard in Resources */, 06EFE9BE2AFAB92000351973 /* Preview Assets.xcassets in Resources */, 06EFE9BB2AFAB92000351973 /* Assets.xcassets in Resources */, ); @@ -622,7 +626,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 162; + CURRENT_PROJECT_VERSION = 265; DEVELOPMENT_ASSET_PATHS = "\"Epicentral/Preview Content\""; DEVELOPMENT_TEAM = DUCAN2M87U; ENABLE_PREVIEWS = YES; @@ -632,6 +636,8 @@ INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.weather"; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen.storyboard; + INFOPLIST_KEY_UIRequiresFullScreen = YES; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; LD_RUNPATH_SEARCH_PATHS = ( @@ -656,7 +662,7 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 162; + CURRENT_PROJECT_VERSION = 265; DEVELOPMENT_ASSET_PATHS = "\"Epicentral/Preview Content\""; DEVELOPMENT_TEAM = DUCAN2M87U; ENABLE_PREVIEWS = YES; @@ -666,6 +672,8 @@ INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.weather"; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen.storyboard; + INFOPLIST_KEY_UIRequiresFullScreen = YES; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; LD_RUNPATH_SEARCH_PATHS = ( @@ -689,7 +697,7 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 162; + CURRENT_PROJECT_VERSION = 265; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 17.2; MARKETING_VERSION = 1.0; @@ -708,7 +716,7 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 162; + CURRENT_PROJECT_VERSION = 265; GENERATE_INFOPLIST_FILE = YES; IPHONEOS_DEPLOYMENT_TARGET = 17.2; MARKETING_VERSION = 1.0; @@ -726,7 +734,7 @@ buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 162; + CURRENT_PROJECT_VERSION = 265; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = com.bsakhuja.PlateUITests; @@ -743,7 +751,7 @@ buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 162; + CURRENT_PROJECT_VERSION = 265; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; PRODUCT_BUNDLE_IDENTIFIER = com.bsakhuja.PlateUITests; diff --git a/Epicentral.xcodeproj/xcuserdata/briansakhuja.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/Epicentral.xcodeproj/xcuserdata/briansakhuja.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist index 1346d36..8ff4d7e 100644 --- a/Epicentral.xcodeproj/xcuserdata/briansakhuja.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist +++ b/Epicentral.xcodeproj/xcuserdata/briansakhuja.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -82,38 +82,6 @@ endingLineNumber = "42" landmarkName = "init(from:)" landmarkType = "7"> - - - - - - + endingLineNumber = "53"> + endingLineNumber = "53"> + endingLineNumber = "79"> @@ -193,38 +158,6 @@ endingLineNumber = "43" landmarkName = "body" landmarkType = "24"> - - - - - - - - - - - - - - - - - - - - UILaunchScreen - - UIColorName - LaunchScreenBackground - UIImageName - LaunchScreen - UIImageRespectsSafeAreaInsets - - - + diff --git a/Epicentral/Models/EarthquakeProperties.swift b/Epicentral/Models/EarthquakeProperties.swift index 06415ba..067624f 100644 --- a/Epicentral/Models/EarthquakeProperties.swift +++ b/Epicentral/Models/EarthquakeProperties.swift @@ -23,6 +23,10 @@ struct EarthquakeProperties: Identifiable { let title: String let url: URL? + var didYouFeelItUrl: URL? { + url?.appendingPathComponent("/tellus") + } + var date: Date { Date(timeIntervalSince1970: time / 1000) } diff --git a/Epicentral/States/EarthquakesState.swift b/Epicentral/States/EarthquakesState.swift index d377812..5c2bdd8 100644 --- a/Epicentral/States/EarthquakesState.swift +++ b/Epicentral/States/EarthquakesState.swift @@ -28,7 +28,7 @@ class EarthquakesState: ObservableObject { .receive(on: RunLoop.main) .sink(receiveCompletion: { data in - }, receiveValue: {[weak self] data in + }, receiveValue: { [weak self] data in self?.earthquakes = data.earthquakes self?.isLoading = false }).store(in: &cancellables) diff --git a/Epicentral/Views/Components/EarthquakeList/EarthquakeRow.swift b/Epicentral/Views/Components/EarthquakeList/EarthquakeRow.swift index 3ead774..802bdee 100644 --- a/Epicentral/Views/Components/EarthquakeList/EarthquakeRow.swift +++ b/Epicentral/Views/Components/EarthquakeList/EarthquakeRow.swift @@ -27,6 +27,7 @@ struct EarthquakeRow: View { .foregroundStyle(Color.gray) Text(earthquake.properties.place ?? "Place") .font(.subheadline) + .multilineTextAlignment(.trailing) } } diff --git a/Epicentral/Views/Components/EarthquakePreviewView.swift b/Epicentral/Views/Components/EarthquakePreviewView.swift index bc3290c..ce84614 100644 --- a/Epicentral/Views/Components/EarthquakePreviewView.swift +++ b/Epicentral/Views/Components/EarthquakePreviewView.swift @@ -16,8 +16,11 @@ struct EarthquakePreviewView: View { var body: some View { VStack { HStack { - Text(earthquake.properties.title) - .font(.headline) + Button(earthquake.properties.title) { + isShowingDetails = true + } + .font(.headline) + .multilineTextAlignment(.leading) Spacer() } HStack { @@ -30,16 +33,6 @@ struct EarthquakePreviewView: View { Spacer() Text(earthquake.properties.date.formatted(.dateTime)) } - if let tsunami = earthquake.properties.tsunami { - HStack { - Text("Tsunami warning") - Spacer() - Text(tsunami ? "Yes" : "No") - } - } - Button("Details") { - isShowingDetails = true - } } .padding() .sheet(isPresented: $isShowingDetails) { diff --git a/Epicentral/Views/Screens/EarthquakeDetailView.swift b/Epicentral/Views/Screens/EarthquakeDetailView.swift index 369c2e7..e3738b1 100644 --- a/Epicentral/Views/Screens/EarthquakeDetailView.swift +++ b/Epicentral/Views/Screens/EarthquakeDetailView.swift @@ -12,23 +12,16 @@ import WebKit struct EarthquakeDetailView: View { let earthquake: Earthquake - + var body: some View { - Map(initialPosition: earthquake.geometry.mapCameraPosition) { - Marker(earthquake.properties.place ?? "Place", coordinate: earthquake.geometry.coordinate2D) + List { - } - .mapControls { -// MapUserLocationButton() -// MapCompass() -// MapScaleView() - } - ScrollView { - VStack(alignment: .leading) { - Text(earthquake.properties.title) - .font(.title) - Spacer() - .frame(height: 24) + // MARK: - Specifics + + Section("Earthquake specifics") { + HStack { + Text(earthquake.properties.title) + } HStack { Text("Magnitude") Spacer() @@ -46,17 +39,44 @@ struct EarthquakeDetailView: View { Text(tsunami ? "Yes" : "No") } } + } + + // MARK: - Location + + Section("Location") { + if let place = earthquake.properties.place { + Text(place) + } + + NavigationLink("View on map") { + Map(initialPosition: earthquake.geometry.mapCameraPosition) { + Marker(earthquake.properties.place ?? "Place", coordinate: earthquake.geometry.coordinate2D) + } + .navigationTitle("Earthquake location") + } + } + + // MARK: - Extra + + Section("Extra") { if let url = earthquake.properties.url { HStack { - Link("View on USGS", destination: url) + Text("Additional details") Spacer() + Link("View on USGS", destination: url) } + } - + if let didYouFeelItURL = earthquake.properties.didYouFeelItUrl { + HStack { + Text("Did you feel it?") + Spacer() + Link("Report to USGS", destination: didYouFeelItURL) + } + } } } - .padding() .navigationTitle("Earthquake details") } } diff --git a/Epicentral/Views/Screens/EarthquakeListView.swift b/Epicentral/Views/Screens/EarthquakeListView.swift index 978677e..7f3c7ee 100644 --- a/Epicentral/Views/Screens/EarthquakeListView.swift +++ b/Epicentral/Views/Screens/EarthquakeListView.swift @@ -34,22 +34,20 @@ struct EarthquakeListView: View { NavigationStack { Group { if let earthquakes = searchResults, earthquakes.count > 0 { - List(earthquakes) { earthquake in - NavigationLink { - EarthquakeDetailView(earthquake: earthquake) - .onAppear { - withAnimation { - state.shouldShowFloatingButton = false - } + ScrollView { + LazyVStack { + ForEach(earthquakes, id: \.self) { earthquake in + NavigationLink { + EarthquakeDetailView(earthquake: earthquake) + .onAppear { + state.shouldShowFloatingButton = false + } + } label: { + EarthquakeRow(earthquake: earthquake) + .padding(.horizontal, 16.0) } - .onDisappear { - withAnimation { - state.shouldShowFloatingButton = true - } - } - - } label: { - EarthquakeRow(earthquake: earthquake) + .accentColor(Color.black) + } } } @@ -60,6 +58,8 @@ struct EarthquakeListView: View { } } .onAppear { + // TODO: Fetch earthquakes only if necessary + state.shouldShowFloatingButton = true state.fetchEarthquakes(startTime: settings.dateStart, endTime: settings.dateEnd) } .onChange(of: settings.dateStart) { diff --git a/Epicentral/Views/Screens/LaunchScreen.storyboard b/Epicentral/Views/Screens/LaunchScreen.storyboard index 3c06afe..14ce3e9 100644 --- a/Epicentral/Views/Screens/LaunchScreen.storyboard +++ b/Epicentral/Views/Screens/LaunchScreen.storyboard @@ -1,8 +1,9 @@ - - + + + - - + + @@ -12,32 +13,31 @@ - + - - + + - + - - + - @@ -45,4 +45,16 @@ + + + + + + + + + + + + diff --git a/Epicentral/Views/Screens/SettingsView.swift b/Epicentral/Views/Screens/SettingsView.swift index e10a6d7..9c2a20a 100644 --- a/Epicentral/Views/Screens/SettingsView.swift +++ b/Epicentral/Views/Screens/SettingsView.swift @@ -14,11 +14,11 @@ struct SettingsView: View { var body: some View { NavigationStack { Form { - Section("Date & Time", content: { + Section("Date & Time") { DatePicker("Start date", selection: $state.dateStart, displayedComponents: .date) DatePicker("End date", selection: $state.dateEnd, displayedComponents: .date) - }) - Section("Magnitude", content: { + } + Section("Magnitude") { Picker("Minimum magnitude", selection: $state.magnitudeLower) { ForEach(state.availableMinMagnitudes, id: \.self) { mag in Text(String(mag)) @@ -31,7 +31,7 @@ struct SettingsView: View { } } - }) + } // Section("Location", content: { // Text("Sorted by distance") // Text("Max distance from location") @@ -48,11 +48,11 @@ struct SettingsView: View { // Text("Location") // }) - Section("About", content: { + Section("About") { Text("Epicentral version \(AppVersionProvider.versionAndBuild)") Text("Made by Brian Sakhuja") Text("Earthquake data from USGS") - }) + } } .navigationTitle("Search Settings")