首页 > 解决方案 > SwiftUI 视图在初始拖动时跳转

问题描述

我正在寻找一个过程,其中卡片从屏幕底部开始并且可以上下拖动(仅限垂直轴)。我有一个问题,在初始拖动时,卡片会从屏幕底部跳到顶部。我已将以下内容简化到最低限度以演示该问题。我在想这是某种坐标空间问题,但是在本地和全局之间进行更改并没有帮助。

    struct ContentView: View {
        @State private var offset = CGSize(width: 0, height: UIScreen.main.bounds.height * 0.9)
        
        var body: some View {
            GeometryReader { geo in
                Color(.red).edgesIgnoringSafeArea(.all)
                Color(.orange)
                    .clipShape(RoundedRectangle(cornerRadius: 20))
                    .offset(offset)
                    .animation(.spring())
                    .gesture(DragGesture()
                        .onChanged { gesture in
                            offset.height = gesture.translation.height
                        }
                    )
            }
        }
}

再次,当手指首先放在底部橙色视图的顶部并且拖动手势开始向上时,橙色视图跳到红色视图的顶部。

标签: swiftui

解决方案


您可以将两个不同的偏移量分隔为两个不同的修改器。首先添加 .offset() 与您的起始金额。然后添加另一个 .offset() 将视图从起始偏移量偏移。

我还添加了一个 .onEnded 手势,以便在开始第二次拖动时不会滞后。您可能想要更改 .onEnded 以便在手势结束时视图动画朝锁定位置。

struct DragView: View {
    @State private var offsetY: CGFloat = 0
    @State private var lastOffsetY: CGFloat = 0
    
    var body: some View {
        GeometryReader { geo in
            Color(.red)
                .ignoresSafeArea()
            
            
            Color(.orange)
                .clipShape(RoundedRectangle(cornerRadius: 20))
                .offset(y: UIScreen.main.bounds.height * 0.8)
                .offset(y: offsetY)
                .animation(.spring())
                .gesture(DragGesture()
                    .onChanged { gesture in
                        withAnimation(.spring()) {
                            offsetY = lastOffsetY + gesture.translation.height
                        }
                    }
                    .onEnded { _ in
                        lastOffsetY = offsetY
                    }
                )
        }
    }
}

推荐阅读