首页 > 解决方案 > SwiftUI:如何根据已经拖动的距离改变拖动速度?

问题描述

例如:我有一个可以自由移动的操纵杆,我怎样才能使拖动随着距离变慢?我拖得越远,拖得越慢。提前致谢。

我的操纵杆代码,拖动有效,但没有界限,如果将其拖动到边缘也不会减慢:

import SwiftUI

struct ContentView: View {

    @State var isDragging = false
    @State var dragValue = CGSize.zero

    var body: some View {
        VStack {
            Text("width: \(dragValue.width)")
            Text("height: \(dragValue.height)")
            VStack (spacing: 16) {
                HStack(spacing: 35) {
                    Image(systemName: "chevron.left")
                        .foregroundColor(.gray)


                    VStack (spacing: 80) {
                        Image(systemName: "chevron.up")
                            .foregroundColor(.gray)
                        Image(systemName: "chevron.down")
                            .foregroundColor(.gray)

                    }
                    Image(systemName: "chevron.right")
                        .foregroundColor(.gray)

                }


            }
            .offset(x: dragValue.width * 0.05, y: dragValue.height * 0.05)

            .frame(width: 150, height: 150)

            .background(LinearGradient(gradient: Gradient(colors: [Color(#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)), Color(#colorLiteral(red: 0.8705882353, green: 0.8941176471, blue: 0.9450980392, alpha: 1))]), startPoint: .top, endPoint: .bottom))
            .clipShape(RoundedRectangle(cornerRadius: isDragging ? (55 - abs(dragValue.height) / 10) : 55, style: .continuous))
            .offset(x: dragValue.width, y: dragValue.height)

            .shadow(color: Color.black.opacity(0.2), radius: 20, x: 0, y: 20)
            .padding(.horizontal, 30)
            .gesture(
                DragGesture().onChanged { value in
                    self.dragValue = value.translation
                    self.isDragging = true
                }
                .onEnded { value in
                    self.dragValue = .zero
                    self.isDragging = false
                }
            )
                .animation(.spring(response: 0.5, dampingFraction: 0.6, blendDuration: 0))
        }

    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

标签: iosswiftiphoneswiftui

解决方案


这是基于渐近曲线的可能解决方案(如果有人发现它有帮助)。使用 Xcode 11.4 / iOS 13.4 测试

演示

更改部分

DragGesture().onChanged { value in
    let limit: CGFloat = 200        // the less the faster resistance 
    let xOff = value.translation.width
    let yOff = value.translation.height
    let dist = sqrt(xOff*xOff + yOff*yOff);
    let factor = 1 / (dist / limit + 1)
    self.dragValue = CGSize(width: value.translation.width * factor,
                        height: value.translation.height * factor)
    self.isDragging = true
}

推荐阅读