diff --git a/Sources/BottomMenu/BottomMenu.swift b/Sources/BottomMenu/BottomMenu.swift index dfb01c87..882c613e 100644 --- a/Sources/BottomMenu/BottomMenu.swift +++ b/Sources/BottomMenu/BottomMenu.swift @@ -143,7 +143,7 @@ private struct BottomMenuWrapper: View { .adaptiveCornerRadius([UIRectCorner.topLeft, .topRight], .grid(3)) .zIndex(2) .transition(.move(edge: .bottom)) - .screenEdgePadding(self.deviceState.isPad ? .horizontal : []) + .screenEdgePadding(self.deviceState.isUsingPadMetrics ? .horizontal : []) } } .ignoresSafeArea() diff --git a/Sources/CubePreview/CubePreviewView.swift b/Sources/CubePreview/CubePreviewView.swift index e9ef4813..1c8dc27c 100644 --- a/Sources/CubePreview/CubePreviewView.swift +++ b/Sources/CubePreview/CubePreviewView.swift @@ -226,17 +226,17 @@ public struct CubePreviewView: View { (Text(self.viewStore.selectedWordString) + self.scoreText .baselineOffset( - (self.deviceState.idiom == .pad ? 2 : 1) * 16 + (self.deviceState.isUsingPadMetrics ? 2 : 1) * 16 ) .font( .custom( .matterMedium, - size: (self.deviceState.idiom == .pad ? 2 : 1) * 20 + size: (self.deviceState.isUsingPadMetrics ? 2 : 1) * 20 ) )) .adaptiveFont( .matterSemiBold, - size: (self.deviceState.idiom == .pad ? 2 : 1) * 32 + size: (self.deviceState.isUsingPadMetrics ? 2 : 1) * 32 ) .opacity(self.viewStore.selectedWordIsFinalWord ? 1 : 0.5) .allowsTightening(true) diff --git a/Sources/GameCore/Views/GameFooterView.swift b/Sources/GameCore/Views/GameFooterView.swift index 07f207f2..ab39ebef 100644 --- a/Sources/GameCore/Views/GameFooterView.swift +++ b/Sources/GameCore/Views/GameFooterView.swift @@ -123,8 +123,8 @@ public struct WordListView: View { reader.scrollTo(SpacerId(), anchor: self.isLeftToRight ? .trailing : .leading) } } - .screenEdgePadding(self.deviceState.isPad ? .leading : []) - .adaptivePadding(self.deviceState.isPhone ? .leading : []) + .screenEdgePadding(self.deviceState.isUsingPadMetrics ? .leading : []) + .adaptivePadding(self.deviceState.isUsingPadMetrics ? [] : .leading) .padding(.vertical) } } diff --git a/Sources/GameCore/Views/GameHeaderView.swift b/Sources/GameCore/Views/GameHeaderView.swift index 9f70804d..c6e71fdd 100644 --- a/Sources/GameCore/Views/GameHeaderView.swift +++ b/Sources/GameCore/Views/GameHeaderView.swift @@ -86,7 +86,7 @@ struct ScoreView: View { ? "(used)" : "" ) - .adaptiveFont(.matterMedium, size: self.deviceState.isPad ? 18 : 14) + .adaptiveFont(.matterMedium, size: self.deviceState.isUsingPadMetrics ? 18 : 14) .alignmentGuide(.top) { _ in 0 } .alignmentGuide(.trailing) { _ in 0 }, alignment: .topTrailing @@ -126,7 +126,7 @@ struct ScoreView: View { } } } - .adaptiveFont(.matterSemiBold, size: self.deviceState.isPad ? 40 : 32) + .adaptiveFont(.matterSemiBold, size: self.deviceState.isUsingPadMetrics ? 40 : 32) .adaptivePadding(.horizontal) } } diff --git a/Sources/GameCore/Views/GameView.swift b/Sources/GameCore/Views/GameView.swift index df80e671..42506035 100644 --- a/Sources/GameCore/Views/GameView.swift +++ b/Sources/GameCore/Views/GameView.swift @@ -65,7 +65,7 @@ public struct GameView: View where Content: View { removal: .game ) ) - .adaptivePadding(self.deviceState.isPad ? .horizontal : [], .grid(30)) + .adaptivePadding(self.deviceState.isUsingPadMetrics ? .horizontal : [], .grid(30)) } else { ProgressView() .progressViewStyle(CircularProgressViewStyle(tint: .adaptiveBlack)) @@ -83,7 +83,7 @@ public struct GameView: View where Content: View { } GameHeaderView(store: self.store) } - .screenEdgePadding(self.deviceState.isPad ? .horizontal : []) + .screenEdgePadding(self.deviceState.isUsingPadMetrics ? .horizontal : []) Spacer() GameFooterView(isAnimationReduced: self.isAnimationReduced, store: self.store) .padding(.bottom) diff --git a/Sources/GameCore/Views/WordSubmitButton.swift b/Sources/GameCore/Views/WordSubmitButton.swift index 16a3565e..a02677dc 100644 --- a/Sources/GameCore/Views/WordSubmitButton.swift +++ b/Sources/GameCore/Views/WordSubmitButton.swift @@ -201,13 +201,13 @@ public struct WordSubmitButton: View { } } .frame( - width: self.deviceState.idiom == .pad ? 100 : 80, - height: self.deviceState.idiom == .pad ? 100 : 80 + width: self.deviceState.isUsingPadMetrics ? 100 : 80, + height: self.deviceState.isUsingPadMetrics ? 100 : 80 ) .background(Circle().fill(Color.adaptiveBlack)) .foregroundColor(.adaptiveWhite) .opacity(self.viewStore.isSelectedWordValid ? 1 : 0.5) - .font(.system(size: self.deviceState.isPad ? 40 : 30)) + .font(.system(size: self.deviceState.isUsingPadMetrics ? 40 : 30)) .adaptivePadding([.all], .grid(4)) // NB: Expand the tappable radius of the button. .background(Color.black.opacity(0.0001)) diff --git a/Sources/Styleguide/DeviceState.swift b/Sources/Styleguide/DeviceState.swift index 112d3df0..4cc95401 100644 --- a/Sources/Styleguide/DeviceState.swift +++ b/Sources/Styleguide/DeviceState.swift @@ -4,45 +4,51 @@ public struct DeviceState { public var idiom: UIUserInterfaceIdiom public var orientation: UIDeviceOrientation public var previousOrientation: UIDeviceOrientation + public var horizontalSizeClass: UserInterfaceSizeClass? public static let `default` = Self( idiom: UIDevice.current.userInterfaceIdiom, orientation: UIDevice.current.orientation, - previousOrientation: UIDevice.current.orientation + previousOrientation: UIDevice.current.orientation, + horizontalSizeClass: nil ) - public var isPad: Bool { - self.idiom == .pad - } - - public var isPhone: Bool { - self.idiom == .phone + public var isUsingPadMetrics: Bool { + self.idiom == .pad && self.horizontalSizeClass != .compact } #if DEBUG public static let phone = Self( idiom: .phone, orientation: .portrait, - previousOrientation: .portrait + previousOrientation: .portrait, + horizontalSizeClass: .compact ) public static let pad = Self( idiom: .pad, orientation: .portrait, - previousOrientation: .portrait + previousOrientation: .portrait, + horizontalSizeClass: .regular ) #endif } public struct DeviceStateModifier: ViewModifier { @State var state: DeviceState = .default + @Environment(\.horizontalSizeClass) var horizontalSizeClass public init() { } public func body(content: Content) -> some View { content - .onAppear() + .onAppear { + self.state.horizontalSizeClass = self.horizontalSizeClass + } + .onChange(of: self.horizontalSizeClass, perform: { value in + self.state.horizontalSizeClass = value + }) .onReceive( NotificationCenter.default.publisher(for: UIDevice.orientationDidChangeNotification) ) { _ in diff --git a/Sources/Styleguide/Padding.swift b/Sources/Styleguide/Padding.swift index 926a4786..30213829 100644 --- a/Sources/Styleguide/Padding.swift +++ b/Sources/Styleguide/Padding.swift @@ -25,14 +25,18 @@ private struct ScreenEdgePadding: ViewModifier { content.adaptivePadding(self.edges) case .pad, .tv, .mac: - content.adaptivePadding( - self.edges, - // NB: clean this up by holding onto previous "valid" orientation. - iPadPadding(for: self.deviceState.orientation) - ?? iPadPadding(for: self.deviceState.previousOrientation) - ?? .grid(20) - ) - + if self.deviceState.isUsingPadMetrics { + content.adaptivePadding( + self.edges, + // NB: clean this up by holding onto previous "valid" orientation. + iPadPadding(for: self.deviceState.orientation) + ?? iPadPadding(for: self.deviceState.previousOrientation) + ?? .grid(20) + ) + } else { + content.adaptivePadding(self.edges) + } + @unknown default: content } diff --git a/Sources/TrailerFeature/Trailer.swift b/Sources/TrailerFeature/Trailer.swift index 87ed79b3..aa10a338 100644 --- a/Sources/TrailerFeature/Trailer.swift +++ b/Sources/TrailerFeature/Trailer.swift @@ -265,17 +265,17 @@ public struct TrailerView: View { (Text(self.viewStore.selectedWordString) + self.scoreText .baselineOffset( - (self.deviceState.idiom == .pad ? 2 : 1) * 16 + (self.deviceState.isUsingPadMetrics ? 2 : 1) * 16 ) .font( .custom( .matterMedium, - size: (self.deviceState.idiom == .pad ? 2 : 1) * 20 + size: (self.deviceState.isUsingPadMetrics ? 2 : 1) * 20 ) )) .adaptiveFont( .matterSemiBold, - size: (self.deviceState.idiom == .pad ? 2 : 1) * 32 + size: (self.deviceState.isUsingPadMetrics ? 2 : 1) * 32 ) .opacity(self.viewStore.selectedWordIsValid ? 1 : 0.5) .allowsTightening(true) @@ -320,7 +320,7 @@ public struct TrailerView: View { ) ) .adaptivePadding( - self.deviceState.idiom == .pad ? .horizontal : [], + self.deviceState.isUsingPadMetrics ? .horizontal : [], .grid(30) ) } @@ -340,7 +340,7 @@ public struct TrailerView: View { ) } .padding( - self.deviceState.idiom == .pad ? .vertical : [], + self.deviceState.isUsingPadMetrics ? .vertical : [], .grid(15) ) .opacity(self.viewStore.opacity) diff --git a/Tests/AppStoreSnapshotTests/AppStorePreview.swift b/Tests/AppStoreSnapshotTests/AppStorePreview.swift index 31ba62e2..66bf08b6 100644 --- a/Tests/AppStoreSnapshotTests/AppStorePreview.swift +++ b/Tests/AppStoreSnapshotTests/AppStorePreview.swift @@ -28,7 +28,7 @@ where var body: some View { ZStack { Group { - if self.deviceState.idiom == .pad { + if self.deviceState.isUsingPadMetrics { Snapshot(self.snapshotting) { ZStack(alignment: .top) { self.snapshotContent() @@ -78,10 +78,10 @@ where } } .clipShape( - RoundedRectangle(cornerRadius: .grid(self.deviceState.idiom == .pad ? 4 : 10), style: .continuous) + RoundedRectangle(cornerRadius: .grid(self.deviceState.isUsingPadMetrics ? 4 : 10), style: .continuous) ) .clipped() - .padding(.grid(self.deviceState.idiom == .pad ? 10 : 4)) + .padding(.grid(self.deviceState.isUsingPadMetrics ? 10 : 4)) .background(Color.black) .clipShape( RoundedRectangle(cornerRadius: .grid(14), style: .continuous) @@ -90,17 +90,17 @@ where RoundedRectangle(cornerRadius: .grid(14), style: .continuous) .stroke(Color.gray, style: StrokeStyle(lineWidth: .grid(1) / 2)) ) - .scaleEffect(self.deviceState.idiom == .pad ? 0.8 : 0.9) - .offset(y: .grid(self.deviceState.idiom == .pad ? 90 : 60)) + .scaleEffect(self.deviceState.isUsingPadMetrics ? 0.8 : 0.9) + .offset(y: .grid(self.deviceState.isUsingPadMetrics ? 90 : 60)) - VStack(spacing: .grid(self.deviceState.idiom == .pad ? 14 : 7)) { - VStack(spacing: .grid(self.deviceState.idiom == .pad ? 14 : 7)) { + VStack(spacing: .grid(self.deviceState.isUsingPadMetrics ? 14 : 7)) { + VStack(spacing: .grid(self.deviceState.isUsingPadMetrics ? 14 : 7)) { Image(systemName: "cube.fill") .foregroundColor(Color.black) - .font(.system(size: self.deviceState.idiom == .pad ? 50 : 30)) + .font(.system(size: self.deviceState.isUsingPadMetrics ? 50 : 30)) self.description() - .font(.custom(.matterMedium, size: self.deviceState.idiom == .pad ? 75 : 36)) + .font(.custom(.matterMedium, size: self.deviceState.isUsingPadMetrics ? 75 : 36)) .multilineTextAlignment(.center) } .foreground( @@ -115,8 +115,8 @@ where Spacer() } - .padding(.horizontal, .grid(self.deviceState.idiom == .pad ? 40 : 10)) - .padding(.vertical, .grid(self.deviceState.idiom == .pad ? 12 : 4)) + .padding(.horizontal, .grid(self.deviceState.isUsingPadMetrics ? 40 : 10)) + .padding(.vertical, .grid(self.deviceState.isUsingPadMetrics ? 12 : 4)) } .frame(maxWidth: .infinity, maxHeight: .infinity) .background(self.backgroundColor.ignoresSafeArea())