From 6c2846a0725d67ce10e2532c8e332a786c4ee882 Mon Sep 17 00:00:00 2001 From: Matt Bruce Date: Sun, 1 Feb 2026 08:57:30 -0600 Subject: [PATCH] Signed-off-by: Matt Bruce --- .../Clock/Views/Components/DigitView.swift | 5 +- .../Views/Components/TimeDisplayView.swift | 48 ++++++++++++++++++- 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/TheNoiseClock/Features/Clock/Views/Components/DigitView.swift b/TheNoiseClock/Features/Clock/Views/Components/DigitView.swift index 6547769..173d0c9 100644 --- a/TheNoiseClock/Features/Clock/Views/Components/DigitView.swift +++ b/TheNoiseClock/Features/Clock/Views/Components/DigitView.swift @@ -92,6 +92,9 @@ struct DigitView: View { .baselineOffset(0) .onAppear { calculateOptimalFontSize(for: geometry.size) + DispatchQueue.main.async { + calculateOptimalFontSize(for: geometry.size) + } } .onChange(of: geometry.size) { _, newSize in calculateOptimalFontSize(for: newSize) @@ -124,7 +127,7 @@ struct DigitView: View { weight: weight, design: design, for: size, - isDisplayMode: isDisplayMode) + isDisplayMode: false) // Only update if the size is significantly different to prevent micro-adjustments fontSize = optimalSize diff --git a/TheNoiseClock/Features/Clock/Views/Components/TimeDisplayView.swift b/TheNoiseClock/Features/Clock/Views/Components/TimeDisplayView.swift index fdfd1fd..165dcb8 100644 --- a/TheNoiseClock/Features/Clock/Views/Components/TimeDisplayView.swift +++ b/TheNoiseClock/Features/Clock/Views/Components/TimeDisplayView.swift @@ -27,6 +27,7 @@ struct TimeDisplayView: View { let forceHorizontalMode: Bool let isDisplayMode: Bool @State var fontSize: CGFloat = 100 + @State private var lastCalculatedContainerSize: CGSize = .zero // MARK: - Formatters private static let hour24DF: DateFormatter = { @@ -137,13 +138,58 @@ struct TimeDisplayView: View { .animation(.smooth(duration: Design.Animation.standard), value: showSeconds) // Smooth animation for seconds toggle .minimumScaleFactor(0.1) .clipped() // Prevent overflow beyond bounds + .onAppear { + updateFontSize(containerSize: containerSize, portrait: portrait, showSeconds: showSeconds) + } + .onChange(of: containerSize) { _, newSize in + updateFontSize(containerSize: newSize, portrait: portrait, showSeconds: showSeconds) + } + .onChange(of: showSeconds) { _, _ in + updateFontSize(containerSize: containerSize, portrait: portrait, showSeconds: showSeconds) + } + .onChange(of: fontFamily) { _, _ in + updateFontSize(containerSize: containerSize, portrait: portrait, showSeconds: showSeconds) + } + .onChange(of: fontWeight) { _, _ in + updateFontSize(containerSize: containerSize, portrait: portrait, showSeconds: showSeconds) + } + .onChange(of: fontDesign) { _, _ in + updateFontSize(containerSize: containerSize, portrait: portrait, showSeconds: showSeconds) + } } //.border(.yellow, width: 1) .frame(maxWidth: .infinity, maxHeight: .infinity) .onOrientationChange() // Force updates on orientation changes } - + // MARK: - Font Sizing + private func updateFontSize(containerSize: CGSize, portrait: Bool, showSeconds: Bool) { + guard containerSize != .zero else { return } + if containerSize == lastCalculatedContainerSize { + return + } + + let rows = portrait ? (showSeconds ? 5.0 : 3.0) : 1.0 + let digits = portrait ? 2.0 : (showSeconds ? 6.0 : 4.0) + let digitSize = CGSize( + width: max(1, containerSize.width / digits), + height: max(1, containerSize.height / rows) + ) + + let estimated = FontUtils.calculateOptimalFontSize( + digit: "8", + fontName: fontFamily, + weight: fontWeight, + design: fontDesign, + for: digitSize, + isDisplayMode: false + ) + + if abs(estimated - fontSize) > 1 { + fontSize = estimated + } + lastCalculatedContainerSize = containerSize + } }