fix(store): replace pinnedViews with ZStack overlay to prevent EXC_BAD_ACCESS crash

pinnedViews + rapid state changes from stretchAmount every frame during overscroll
triggers SwiftUI memory corruption. ZStack overlay approach is crash-free:
- LazyVStack with no pinnedViews
- Inline tabs fade out when pinned threshold reached
- Overlay tabs (with safeAreaTop padding) fade in at top of ZStack
This commit is contained in:
Daniel Arantes Loverde
2026-06-03 15:20:44 -03:00
parent 82ab29388f
commit c89c80e8d1

View File

@@ -46,25 +46,39 @@ struct StoreDetailView: View {
let coverVisibleUntilY: CGFloat = 253 let coverVisibleUntilY: CGFloat = 253
let storeLogoSize: CGFloat = 84 let storeLogoSize: CGFloat = 84
var safeAreaTop: CGFloat {
#if canImport(UIKit)
return UIDevice.appSafeAreaTop
#else
return 0
#endif
}
var body: some View { var body: some View {
ScrollViewReader { proxy in ScrollViewReader { proxy in
ScrollView(showsIndicators: false) { ZStack(alignment: .top) {
ScrollOffsetReader(offsetY: $scrollOffset) ScrollView(showsIndicators: false) {
LazyVStack(spacing: 0, pinnedViews: [.sectionHeaders]) { ScrollOffsetReader(offsetY: $scrollOffset)
topSection LazyVStack(spacing: 0) {
Section { topSection
categoryTabs(proxy: proxy, isPinned: false)
.opacity(isCategoryTabsPinned ? 0 : 1)
sectionedProducts sectionedProducts
} header: {
categoryTabs(proxy: proxy, isPinned: isCategoryTabsPinned)
} }
} }
} .coordinateSpace(name: StoreDetailScrollCoordinateSpace.name)
.coordinateSpace(name: StoreDetailScrollCoordinateSpace.name) .refreshable {
.refreshable { await loadStoreData(forceRefresh: true)
await loadStoreData(forceRefresh: true) }
.ignoresSafeArea(edges: .top)
.background(AppColors.backgroundLight)
categoryTabs(proxy: proxy, isPinned: true)
.opacity(isCategoryTabsPinned ? 1 : 0)
.allowsHitTesting(isCategoryTabsPinned)
.zIndex(10)
} }
.ignoresSafeArea(edges: .top) .ignoresSafeArea(edges: .top)
.background(AppColors.backgroundLight)
.saturation(isStoreOpen ? 1 : 0) .saturation(isStoreOpen ? 1 : 0)
} }
.navigationBarBackButtonHidden(true) .navigationBarBackButtonHidden(true)