ScrollView-VerhaltenIOS

Programmierung für iOS
Anonymous
 ScrollView-Verhalten

Post by Anonymous »

Sollte B über A in Zstack sein, muss der Scroll-Offset 200 betragen (Höhe von A). Entweder ist B oben fixiert und hat einen Versatz von 200, oder B beginnt bei 200 Y-Position und wenn wir nach oben scrollen, ändert sich auch sein Y-Wert, so dass es nach einer Verschiebung um 200 Punkte nach oben A vollständig abdeckt. Welcher Teil von A auch immer sichtbar ist, muss interaktiv sein, egal wie wir dies angehen. B sollte über A scrollen.
Ich habe die folgende Version erreicht, vertraue ihr aber nicht allzu sehr und sie ist auch nicht sehr flüssig.

Code: Select all

// MARK: - B over A with dynamic offset; A interactive while visible
struct CollapsingOverlayScrollExample: View {
private let headerHeight: CGFloat = 200
@State private var scrolledUp: CGFloat = 0
@State private var baselineTop: CGFloat? = nil
@State private var displayedScrolledUp: CGFloat = 0

var body: some View {
ZStack(alignment: .top) {
// View A (Header) behind
VStack {
Text("👆 Tap Header (A)")
.font(.headline)
.foregroundColor(.white)
Text("Visible part remains interactive")
.foregroundColor(.white)
}
.frame(height: headerHeight)
.frame(maxWidth: .infinity)
.background(Color.blue)
.onTapGesture {
print("👉 Header (A) tapped!")
}
.zIndex(0)

// View B (ScrollView) on top, offset down by remaining visible header
ScrollView {
VStack(spacing: 20) {
// Sentinel to track scroll offset within the ScrollView
GeometryReader { geo in
Color.clear
.preference(key: ScrollOffsetKey.self,
value: geo.frame(in: .named("ROOT")).minY)
}
.frame(height: 0)

ForEach(1...30, id: \.self) { i in
Text("Scroll Item \(i)")
.frame(maxWidth: .infinity)
.frame(height: 60)
.background(Color.orange.opacity(0.9))
.cornerRadius(8)
.padding(.horizontal)
}
}
.padding(.top, 16)
}
.background(Color.green.opacity(0.5))
// While header is visible, keep B's frame below it so A remains tappable
.offset(y: max(0, headerHeight - displayedScrolledUp))
.zIndex(1)
}
.coordinateSpace(name: "ROOT")
.onPreferenceChange(ScrollOffsetKey.self) { topInRoot in
// Calibrate baseline once to avoid initial jump due to layout timing.
if baselineTop == nil {
baselineTop = topInRoot
}
let base = baselineTop ?? headerHeight
// Positive distance scrolled upwards relative to the baseline.
let delta = base - topInRoot
scrolledUp = max(0, delta)
}
.onChange(of: scrolledUp) { newValue in
withAnimation(.interactiveSpring(response: 0.25, dampingFraction: 0.86, blendDuration: 0.2)) {
displayedScrolledUp = newValue
}
}
.edgesIgnoringSafeArea(.all)
}
}

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post