From 217bd6779e81f50d81417e8748a0fb7ba744fa87 Mon Sep 17 00:00:00 2001 From: mntone <901816+mntone@users.noreply.github.com> Date: Tue, 23 Jan 2024 16:20:37 +0900 Subject: [PATCH] Adds SizeObservers. --- .../Views/Modifiers/SizeChangeModifier.swift | 19 +++++++++ .../Views/Modifiers/WidthChangeModifier.swift | 29 -------------- .../Views/Navigations/ColumnContentView.swift | 39 +++++++++---------- src/App/Views/Utils/SizeObserver.swift | 31 +++++++++++++++ src/MonsterAnalyzer.xcodeproj/project.pbxproj | 18 ++++++--- 5 files changed, 81 insertions(+), 55 deletions(-) create mode 100644 src/App/Views/Modifiers/SizeChangeModifier.swift delete mode 100644 src/App/Views/Modifiers/WidthChangeModifier.swift create mode 100644 src/App/Views/Utils/SizeObserver.swift diff --git a/src/App/Views/Modifiers/SizeChangeModifier.swift b/src/App/Views/Modifiers/SizeChangeModifier.swift new file mode 100644 index 0000000..2f30550 --- /dev/null +++ b/src/App/Views/Modifiers/SizeChangeModifier.swift @@ -0,0 +1,19 @@ +import SwiftUI + +extension View { + @inline(__always) + @ViewBuilder + func onWidthChange(perform: @escaping (CGFloat) -> Void) -> some View { + background { + WidthObserver(perform: perform) + } + } + + @inline(__always) + @ViewBuilder + func onHeightChange(perform: @escaping (CGFloat) -> Void) -> some View { + background { + HeightObserver(perform: perform) + } + } +} diff --git a/src/App/Views/Modifiers/WidthChangeModifier.swift b/src/App/Views/Modifiers/WidthChangeModifier.swift deleted file mode 100644 index eaacad8..0000000 --- a/src/App/Views/Modifiers/WidthChangeModifier.swift +++ /dev/null @@ -1,29 +0,0 @@ -import SwiftUI - -struct _WidthChangeModifier: ViewModifier { - let perform: (CGFloat) -> Void - - func body(content: Content) -> some View { - content.background { - GeometryReader { proxy in - Color.clear - .onAppear { - perform(proxy.size.width) - } -#if !os(watchOS) - .onChange(of: proxy.size.width) { newValue in - perform(newValue) - } -#endif - } - } - } -} - -extension View { - @inline(__always) - @ViewBuilder - func onWidthChange(perform: @escaping (CGFloat) -> Void) -> ModifiedContent { - modifier(_WidthChangeModifier(perform: perform)) - } -} diff --git a/src/App/Views/Navigations/ColumnContentView.swift b/src/App/Views/Navigations/ColumnContentView.swift index ae4194f..cd9ddee 100644 --- a/src/App/Views/Navigations/ColumnContentView.swift +++ b/src/App/Views/Navigations/ColumnContentView.swift @@ -14,7 +14,7 @@ private struct _NavigationSplitViewHost: View { private var horizontalSizeClass @State - private var screenWidth: CGFloat = 0 + private var isWideMode: Bool = false #endif var body: some View { @@ -37,41 +37,40 @@ private struct _NavigationSplitViewHost: View { } detail: { MonsterColumn() } - .background { - GeometryReader { proxy in - Color.clear.onChangeBackport(of: proxy.size.width, initial: true) { _, newValue in - screenWidth = newValue + .onWidthChange { screenWidth in + if screenWidth >= 1024 { + guard !isWideMode else { return } + + isWideMode = true + if columnVisibility == .detailOnly { + columnVisibility = .doubleColumn + } + } else { + guard isWideMode else { return } + + isWideMode = false + if columnVisibility != .detailOnly, + selectedMonsterID != nil { + columnVisibility = .detailOnly } } } .block { content in - if screenWidth >= 1024 { + if isWideMode { content.navigationSplitViewStyle(.balanced) } else{ content.navigationSplitViewStyle(.prominentDetail) } } .onAppear { - guard screenWidth < 1024 else { return } + guard !isWideMode else { return } if selectedMonsterID != nil { columnVisibility = .detailOnly } } - .onChange(of: screenWidth) { newValue in - if screenWidth >= 1024 { - if columnVisibility == .detailOnly { - columnVisibility = .doubleColumn - } - } else { - if columnVisibility != .detailOnly, - selectedMonsterID != nil { - columnVisibility = .detailOnly - } - } - } .onChange(of: selectedMonsterID) { newValue in - guard screenWidth < 1024 else { return } + guard !isWideMode else { return } if newValue != nil { columnVisibility = .detailOnly diff --git a/src/App/Views/Utils/SizeObserver.swift b/src/App/Views/Utils/SizeObserver.swift new file mode 100644 index 0000000..67b2518 --- /dev/null +++ b/src/App/Views/Utils/SizeObserver.swift @@ -0,0 +1,31 @@ +import SwiftUI + +struct WidthObserver: View { + let perform: (CGFloat) -> Void + + var body: some View { + GeometryReader { proxy in + Color.clear + .onAppear { + let width = proxy.size.width + perform(width) + } + .onChange(of: proxy.size.width, perform: perform) + } + } +} + +struct HeightObserver: View { + let perform: (CGFloat) -> Void + + var body: some View { + GeometryReader { proxy in + Color.clear + .onAppear { + let height = proxy.size.height + perform(height) + } + .onChange(of: proxy.size.height, perform: perform) + } + } +} diff --git a/src/MonsterAnalyzer.xcodeproj/project.pbxproj b/src/MonsterAnalyzer.xcodeproj/project.pbxproj index 58c93ae..d83b433 100644 --- a/src/MonsterAnalyzer.xcodeproj/project.pbxproj +++ b/src/MonsterAnalyzer.xcodeproj/project.pbxproj @@ -79,8 +79,8 @@ EB5672272B57D60D00592413 /* MAForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB5672262B57D60D00592413 /* MAForm.swift */; }; EB5672282B57D60D00592413 /* MAForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB5672262B57D60D00592413 /* MAForm.swift */; }; EB56722C2B57F5E400592413 /* AccessibilityNumberWeaknessSectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB56722B2B57F5E400592413 /* AccessibilityNumberWeaknessSectionView.swift */; }; - EB56722E2B580E3700592413 /* WidthChangeModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB56722D2B580E3700592413 /* WidthChangeModifier.swift */; }; - EB56722F2B580E3700592413 /* WidthChangeModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB56722D2B580E3700592413 /* WidthChangeModifier.swift */; }; + EB56722E2B580E3700592413 /* SizeChangeModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB56722D2B580E3700592413 /* SizeChangeModifier.swift */; }; + EB56722F2B580E3700592413 /* SizeChangeModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB56722D2B580E3700592413 /* SizeChangeModifier.swift */; }; EB58FB6F2B5C9BE600A4B975 /* MobileMetrics.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB58FB6E2B5C9BE600A4B975 /* MobileMetrics.swift */; platformFilter = ios; }; EB5941CE2B39ABD1005BC27C /* MonsterAnalyzerWatch.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = EBB4B1F22B17593F004D63EA /* MonsterAnalyzerWatch.app */; platformFilter = ios; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; EB6297F22B37179200E830E6 /* View+Block.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB6297F12B37179200E830E6 /* View+Block.swift */; }; @@ -131,6 +131,8 @@ EB7DAA662B4FD3410003210E /* MonsterColumn.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB7DAA652B4FD3410003210E /* MonsterColumn.swift */; }; EB7DAA682B4FD36D0003210E /* MonsterPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB7DAA672B4FD36D0003210E /* MonsterPage.swift */; }; EB7DAA692B4FD36D0003210E /* MonsterPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB7DAA672B4FD36D0003210E /* MonsterPage.swift */; }; + EB8201D42B5F97A000A8FDDD /* SizeObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB8201D32B5F97A000A8FDDD /* SizeObserver.swift */; }; + EB8201D52B5F97A000A8FDDD /* SizeObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB8201D32B5F97A000A8FDDD /* SizeObserver.swift */; }; EB84A5BD2B47873B00291C6B /* DeveloperSettingsPane.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB84A5BC2B47873B00291C6B /* DeveloperSettingsPane.swift */; }; EB84A5BE2B47873B00291C6B /* DeveloperSettingsPane.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB84A5BC2B47873B00291C6B /* DeveloperSettingsPane.swift */; }; EB84A5C02B47910000291C6B /* DeveloperSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB84A5BF2B47910000291C6B /* DeveloperSection.swift */; }; @@ -456,7 +458,7 @@ EB5672232B57CB1B00592413 /* MAFormSeparatedRoundedBackground.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MAFormSeparatedRoundedBackground.swift; sourceTree = ""; }; EB5672262B57D60D00592413 /* MAForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MAForm.swift; sourceTree = ""; }; EB56722B2B57F5E400592413 /* AccessibilityNumberWeaknessSectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessibilityNumberWeaknessSectionView.swift; sourceTree = ""; }; - EB56722D2B580E3700592413 /* WidthChangeModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidthChangeModifier.swift; sourceTree = ""; }; + EB56722D2B580E3700592413 /* SizeChangeModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SizeChangeModifier.swift; sourceTree = ""; }; EB58FB6E2B5C9BE600A4B975 /* MobileMetrics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MobileMetrics.swift; sourceTree = ""; }; EB6297F12B37179200E830E6 /* View+Block.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View+Block.swift"; sourceTree = ""; }; EB6437912B46EE3B00E8D02B /* SwipeAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwipeAction.swift; sourceTree = ""; }; @@ -486,6 +488,7 @@ EB7DAA5E2B4FCBF20003210E /* MonsterList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MonsterList.swift; sourceTree = ""; }; EB7DAA652B4FD3410003210E /* MonsterColumn.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MonsterColumn.swift; sourceTree = ""; }; EB7DAA672B4FD36D0003210E /* MonsterPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MonsterPage.swift; sourceTree = ""; }; + EB8201D32B5F97A000A8FDDD /* SizeObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SizeObserver.swift; sourceTree = ""; }; EB84A5BC2B47873B00291C6B /* DeveloperSettingsPane.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperSettingsPane.swift; sourceTree = ""; }; EB84A5BF2B47910000291C6B /* DeveloperSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeveloperSection.swift; sourceTree = ""; }; EB86E2802B4EC8CE00A06718 /* ci_post_xcodebuild.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = ci_post_xcodebuild.sh; sourceTree = ""; }; @@ -1071,6 +1074,7 @@ EB4426AD2B58AB1C0074B1FF /* HorizontalLayoutMargin.swift */, EB71C1412B5BBEBF0013FBBC /* ScrollViewOffsetDetector.swift */, EB8AD06D2B42946A00F1E96F /* ShapeStyle+Hierarchical.swift */, + EB8201D32B5F97A000A8FDDD /* SizeObserver.swift */, EB6297F12B37179200E830E6 /* View+Block.swift */, EB87782D2B26E4F200B3359C /* View+OnChangeBackport.swift */, ); @@ -1101,9 +1105,9 @@ children = ( EB6FF1DE2B48F03200118E0F /* PreferredVerticalPaddingModifier.swift */, EB97F6A72B31BCDE00E31602 /* SharedGameListModifier.swift */, + EB56722D2B580E3700592413 /* SizeChangeModifier.swift */, EB560BD32B4386D700E91E01 /* StateOverlayModifier.swift */, EBCA22282B21A58C00C487AD /* ToolbarItemBackportModifier.swift */, - EB56722D2B580E3700592413 /* WidthChangeModifier.swift */, ); path = Modifiers; sourceTree = ""; @@ -1604,6 +1608,8 @@ EB6ADE752B3660340010BD64 /* SharedSettingsPaneModifier.swift in Sources */, EB56720D2B57870200592413 /* SignWeaknessItemView.swift in Sources */, EB5672122B578FFD00592413 /* SignWeaknessSectionView.swift in Sources */, + EB56722F2B580E3700592413 /* SizeChangeModifier.swift in Sources */, + EB8201D52B5F97A000A8FDDD /* SizeObserver.swift in Sources */, EBBF86212B4692D500F76D03 /* Sort+Extensions.swift in Sources */, EB645A612B26749E00D27500 /* StackContentView.swift in Sources */, EB693EA82B3B9F9700CDEC6F /* StarSwingsError+Extensions.swift in Sources */, @@ -1624,7 +1630,6 @@ EBB4B21C2B176CE7004D63EA /* WeaknessView.swift in Sources */, EB5672192B57935300592413 /* WeaknessViewMetrics.swift in Sources */, EBB4B2152B175DE7004D63EA /* WeaknessViewModel.swift in Sources */, - EB56722F2B580E3700592413 /* WidthChangeModifier.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1812,6 +1817,8 @@ EB645A642B2685D500D27500 /* Sidebar.swift in Sources */, EB56720C2B57870200592413 /* SignWeaknessItemView.swift in Sources */, EB5672112B578FFD00592413 /* SignWeaknessSectionView.swift in Sources */, + EB56722E2B580E3700592413 /* SizeChangeModifier.swift in Sources */, + EB8201D42B5F97A000A8FDDD /* SizeObserver.swift in Sources */, EBBF86202B4692D500F76D03 /* Sort+Extensions.swift in Sources */, EBC051102B54C8A200D084E2 /* SortToolbarMenu.swift in Sources */, EB645A652B269EF300D27500 /* StackContentView.swift in Sources */, @@ -1832,7 +1839,6 @@ EBCA222E2B228C6800C487AD /* WeaknessView.swift in Sources */, EB5672182B57935300592413 /* WeaknessViewMetrics.swift in Sources */, EBB4B1C52B15BDA7004D63EA /* WeaknessViewModel.swift in Sources */, - EB56722E2B580E3700592413 /* WidthChangeModifier.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };