Use light glass background for tvOS player control buttons

This commit is contained in:
Arkadiusz Fal
2026-05-07 18:36:47 +02:00
parent c8bb13e229
commit c2758b0d0c
2 changed files with 32 additions and 15 deletions

View File

@@ -68,11 +68,11 @@ struct GlassBackgroundModifier: ViewModifier {
if #available(iOS 26.0, *) { if #available(iOS 26.0, *) {
content.modifier(LiquidGlassModifier(style: style, shape: shape, colorScheme: colorScheme)) content.modifier(LiquidGlassModifier(style: style, shape: shape, colorScheme: colorScheme))
} else { } else {
content.modifier(FallbackGlassModifier(shape: shape, material: fallbackMaterial)) content.modifier(FallbackGlassModifier(shape: shape, material: fallbackMaterial, colorScheme: colorScheme))
} }
#else #else
// macOS doesn't have glassEffect, always use fallback material // macOS / tvOS don't have glassEffect, always use fallback material
content.modifier(FallbackGlassModifier(shape: shape, material: fallbackMaterial)) content.modifier(FallbackGlassModifier(shape: shape, material: fallbackMaterial, colorScheme: colorScheme))
#endif #endif
} }
} }
@@ -127,6 +127,7 @@ private struct LiquidGlassModifier: ViewModifier {
private struct FallbackGlassModifier: ViewModifier { private struct FallbackGlassModifier: ViewModifier {
let shape: GlassShape let shape: GlassShape
let material: GlassFallbackMaterial let material: GlassFallbackMaterial
let colorScheme: ColorScheme?
func body(content: Content) -> some View { func body(content: Content) -> some View {
switch shape { switch shape {
@@ -147,6 +148,15 @@ private struct FallbackGlassModifier: ViewModifier {
@ViewBuilder @ViewBuilder
private var materialBackground: some View { private var materialBackground: some View {
if let colorScheme {
rawMaterialBackground.environment(\.colorScheme, colorScheme)
} else {
rawMaterialBackground
}
}
@ViewBuilder
private var rawMaterialBackground: some View {
switch material { switch material {
case .ultraThinMaterial: case .ultraThinMaterial:
Rectangle().fill(.ultraThinMaterial) Rectangle().fill(.ultraThinMaterial)

View File

@@ -353,9 +353,11 @@ struct TVActionButtonStyle: ButtonStyle {
.minimumScaleFactor(0.8) .minimumScaleFactor(0.8)
.padding(.horizontal, 20) .padding(.horizontal, 20)
.frame(minWidth: 100, minHeight: 80) .frame(minWidth: 100, minHeight: 80)
.background( .glassBackground(
RoundedRectangle(cornerRadius: 12) isFocused ? .tinted(.white.opacity(0.35)) : .regular,
.fill(isFocused ? .white.opacity(0.3) : .white.opacity(0.1)) in: .rect(cornerRadius: 12),
fallback: isFocused ? .ultraThickMaterial : .ultraThinMaterial,
colorScheme: .light
) )
.scaleEffect(configuration.isPressed ? 0.95 : (isFocused ? 1.05 : 1.0)) .scaleEffect(configuration.isPressed ? 0.95 : (isFocused ? 1.05 : 1.0))
.animation(.easeInOut(duration: 0.15), value: isFocused) .animation(.easeInOut(duration: 0.15), value: isFocused)
@@ -371,14 +373,17 @@ struct TVTransportButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View { func makeBody(configuration: Configuration) -> some View {
let size: CGFloat = isPrimary ? 88 : 72 let size: CGFloat = isPrimary ? 88 : 72
let style: GlassStyle = {
if isPrimary {
return isFocused ? .tinted(.white.opacity(0.85)) : .tinted(.white.opacity(0.35))
} else {
return isFocused ? .tinted(.white.opacity(0.35)) : .regular
}
}()
let fallback: GlassFallbackMaterial = (isFocused || isPrimary) ? .ultraThickMaterial : .ultraThinMaterial
return configuration.label return configuration.label
.frame(width: size, height: size) .frame(width: size, height: size)
.background( .glassBackground(style, in: .circle, fallback: fallback, colorScheme: .light)
Circle()
.fill(isFocused
? (isPrimary ? .white.opacity(0.95) : .white.opacity(0.3))
: (isPrimary ? .white.opacity(0.25) : .white.opacity(0.12)))
)
.foregroundStyle(isFocused && isPrimary ? Color.black : .white) .foregroundStyle(isFocused && isPrimary ? Color.black : .white)
.scaleEffect(configuration.isPressed ? 0.92 : (isFocused ? 1.08 : 1.0)) .scaleEffect(configuration.isPressed ? 0.92 : (isFocused ? 1.08 : 1.0))
.animation(.easeInOut(duration: 0.15), value: isFocused) .animation(.easeInOut(duration: 0.15), value: isFocused)
@@ -394,9 +399,11 @@ struct TVCloseButtonStyle: ButtonStyle {
configuration.label configuration.label
.foregroundStyle(.white) .foregroundStyle(.white)
.frame(width: 64, height: 64) .frame(width: 64, height: 64)
.background( .glassBackground(
Circle() isFocused ? .tinted(.white.opacity(0.35)) : .regular,
.fill(isFocused ? .white.opacity(0.3) : .white.opacity(0.12)) in: .circle,
fallback: isFocused ? .ultraThickMaterial : .ultraThinMaterial,
colorScheme: .light
) )
.scaleEffect(configuration.isPressed ? 0.92 : (isFocused ? 1.08 : 1.0)) .scaleEffect(configuration.isPressed ? 0.92 : (isFocused ? 1.08 : 1.0))
.animation(.easeInOut(duration: 0.15), value: isFocused) .animation(.easeInOut(duration: 0.15), value: isFocused)