Post

Replies

Boosts

Views

Activity

Problem with ScrollView in scroll offset IOS 17
I have a problem with the SwiftUI component in the beta version of iOS 17. In iOS 16, the "parallaxedView" element would stretch its height when scrolling to the top of the screen, and upon releasing the finger, the height would return to its original value. In version 17, it doesn't seem to be working. The "scrollOffset" value attempts to be set, but quickly returns to 0, which prevents the container's height from changing. What could be the issue? Here's the simplified component code: private struct ScrollOffsetPreferenceKey: PreferenceKey { static var defaultValue: CGFloat = .zero static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {} } struct ParallaxView<ParallaxedView: View, ContentView: View>: View { private let parallaxedView: () -> ParallaxedView private let contentView: (_ containerHeight: CGFloat) -> ContentView private let navBarHeight: CGFloat = 80 private let maxParallaxedViewHeight: CGFloat = 390 private let buttonSize: CGFloat = 50 @State var scrollOffset: CGFloat = 0 @State var cachedLastOffset: CGFloat = 0 @State private var containerHeight: CGFloat = 0 private var parallaxedViewHeight: CGFloat { min(UIScreen.main.bounds.size.width, maxParallaxedViewHeight) } @inlinable public init( @ViewBuilder parallaxedView: @escaping () -> ParallaxedView, @ViewBuilder contentView: @escaping (_ containerHeight: CGFloat) -> ContentView ) { self.parallaxedView = parallaxedView self.contentView = contentView } var body: some View { GeometryReader { geometry in let inset = geometry.safeAreaInsets.top let shadowOffset = max(0, min(1, ((scrollOffset) / (parallaxedViewHeight - (inset + navBarHeight))))) ZStack(alignment: .topTrailing) { ScrollView { ZStack(alignment: .topTrailing) { VStack(spacing: 0) { GeometryReader { geometry in let scrollOffsetInner = -geometry.frame(in: .named("scroll")).minY Color.clear .preference( key: ScrollOffsetPreferenceKey.self, value: scrollOffsetInner ) } .frame(height: 0) .onPreferenceChange(ScrollOffsetPreferenceKey.self, perform: { offset in self.scrollOffset = CGFloat(offset) }) parallaxedView() .frame(height: parallaxedViewHeight + max(-scrollOffset, 0)) .offset(y: scrollOffset / (scrollOffset > 0 ? 2 : 1)) contentView(self.containerHeight) .background(Color("Background")) .offset(y: -max(-scrollOffset, 0)) } GeometryReader { geometry in Color.clear .onChange(of: geometry.frame(in: .named("scroll")).minY, initial: true) { _, _ in self.containerHeight = geometry.size.height } .onAppear { self.containerHeight = geometry.size.height } .frame(minHeight: 0, maxHeight: .infinity) .frame(width: 10) .zIndex(10) } } .padding(.bottom, 15) } .edgesIgnoringSafeArea(SwiftUI.Edge.Set.top) GeometryReader { geometry in VStack(spacing: 0) { Color("Background") .frame(height: geometry.safeAreaInsets.top + navBarHeight - 5) Color("Background") .frame(height: 5) .shadow(color: Color("Black").opacity(0.15), radius: 2, x: 0, y: 4) } .offset(y: -geometry.safeAreaInsets.top) .opacity(shadowOffset) } } } } }
1
4
2.6k
Sep ’23