From d2189bb701da33e0a43fa300e6a6d9ef1eab4fdc Mon Sep 17 00:00:00 2001 From: Daniel Arantes Loverde Date: Wed, 3 Jun 2026 15:01:23 -0300 Subject: [PATCH] feat(store): stretch cover image on pull-down overscroll - Remove max(0) clamp in ScrollOffsetReader to allow negative values during bounce - Add stretchAmount computed var (max(0, -scrollOffset)) - Hero image frame grows by stretchAmount and offsets upward on overscroll - isCategoryTabsPinned still uses max(0, scrollOffset) via >= check --- .../Sources/PediFoods/Views/Main/StoreDetailSupport.swift | 2 +- .../PediFoods/Views/Main/StoreDetailView+Components.swift | 3 ++- pedi-foods/Sources/PediFoods/Views/Main/StoreDetailView.swift | 1 + 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pedi-foods/Sources/PediFoods/Views/Main/StoreDetailSupport.swift b/pedi-foods/Sources/PediFoods/Views/Main/StoreDetailSupport.swift index c07efd1..1e52f7d 100644 --- a/pedi-foods/Sources/PediFoods/Views/Main/StoreDetailSupport.swift +++ b/pedi-foods/Sources/PediFoods/Views/Main/StoreDetailSupport.swift @@ -37,7 +37,7 @@ struct ScrollOffsetReader: View { ) .onPreferenceChange(ScrollOffsetPreferenceKey.self) { minY in if baseline == nil { baseline = minY } - let offset = max(0, (baseline ?? 0) - minY) + let offset = (baseline ?? 0) - minY if abs(offsetY - offset) > 0.5 { offsetY = offset } diff --git a/pedi-foods/Sources/PediFoods/Views/Main/StoreDetailView+Components.swift b/pedi-foods/Sources/PediFoods/Views/Main/StoreDetailView+Components.swift index 41b03ee..05396ae 100644 --- a/pedi-foods/Sources/PediFoods/Views/Main/StoreDetailView+Components.swift +++ b/pedi-foods/Sources/PediFoods/Views/Main/StoreDetailView+Components.swift @@ -26,7 +26,7 @@ extension StoreDetailView { var heroSection: some View { ZStack(alignment: .top) { AsyncStoreImage(imageURL: resolvedURL(storeCoverURL)) - .frame(height: topSectionHeight) + .frame(height: topSectionHeight + stretchAmount) .overlay( LinearGradient( colors: [Color.black.opacity(0.32), Color.black.opacity(0.05)], @@ -34,6 +34,7 @@ extension StoreDetailView { endPoint: .bottom ) ) + .offset(y: -stretchAmount) .ignoresSafeArea(.container, edges: .top) VStack(spacing: 0) { diff --git a/pedi-foods/Sources/PediFoods/Views/Main/StoreDetailView.swift b/pedi-foods/Sources/PediFoods/Views/Main/StoreDetailView.swift index 5b96dd9..4d5bba6 100644 --- a/pedi-foods/Sources/PediFoods/Views/Main/StoreDetailView.swift +++ b/pedi-foods/Sources/PediFoods/Views/Main/StoreDetailView.swift @@ -38,6 +38,7 @@ struct StoreDetailView: View { @State var scrollOffset: CGFloat = 0 var isCategoryTabsPinned: Bool { scrollOffset >= topSectionHeight } + var stretchAmount: CGFloat { max(0, -scrollOffset) } let cardTopInset: CGFloat = 180 let summaryCardBaseHeight: CGFloat = 212