You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在SwiftUI中复刻Wallet应用的滚动返回主视图效果?

复刻Wallet应用的SwiftUI滚动行为

我正在尝试在SwiftUI中复刻Wallet应用的滚动行为——具体来说,实现向上滚动卡片视图至顶端后返回主视图的效果。

我写了以下代码,但当前效果和Wallet应用的预期行为不符,希望能得到修改指导:

struct ContentView: View {
    @State private var isCardVisible = true
    @State private var dragOffset: CGFloat = 0
    
    var body: some View {
        ZStack {
            Color.gray.ignoresSafeArea()
            
            if isCardVisible {
                ScrollView {
                    VStack(spacing: 20) {
                        Text("Card View")
                            .font(.largeTitle)
                            .padding()
                            .background(Color.white)
                            .cornerRadius(8)
                            .offset(y: max(dragOffset, 0))
                            .gesture(
                                DragGesture()
                                    .onChanged { value in
                                        dragOffset = value.translation.height
                                    }
                                    .onEnded { value in
                                        if dragOffset < -200 {
                                            isCardVisible = false
                                        } else {
                                            dragOffset = 0
                                        }
                                    }
                            )
                    }
                    .padding()
                }
                .overlay(
                    GeometryReader { geometry in
                        Color.clear
                            .preference(key: OffsetPreferenceKey.self, value: geometry.frame(in: .global).origin.y)
                    }
                )
                .onPreferenceChange(OffsetPreferenceKey.self) { offset in
                    if offset < -200 {
                        isCardVisible = false
                    }
                }
            }
            
            if !isCardVisible {
                Button("Show Card") {
                    isCardVisible = true
                }
                .padding()
                .foregroundColor(.white)
                .background(Color.blue)
                .cornerRadius(8)
            }
        }
    }
}

struct OffsetPreferenceKey: PreferenceKey {
    static var defaultValue: CGFloat = 0
    
    static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
        value = nextValue()
    }
}

我的实现思路:

  • 用ZStack层叠视图,把卡片放在ScrollView里支持滚动
  • 用dragOffset状态变量追踪卡片的垂直拖拽偏移量
  • 给卡片加DragGesture,向上滚动松开后如果偏移量小于-200,就隐藏卡片返回主视图
  • 同时通过Overlay结合GeometryReader检测滚动偏移,用PreferenceKey追踪偏移值,判断是否触发退出

现在滚动效果和预期不符,恳请指导修改代码以精准复刻Wallet应用的行为。


内容的提问来源于stack exchange,提问作者Soltan Adel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 12:30:25