[英]SwiftUI: How to change the speed of drag based on distance already dragged?
For example: I have a joystick that can be moved around freely, how can I make the dragging slower with distance?例如:我有一个可以自由移动的操纵杆,我怎样才能让拖动随着距离变慢? The further I drag the joystick, the slower the drag is.
我拖动操纵杆越远,拖动速度越慢。 Thanks in advance.
提前致谢。
My Joystick code, dragging works but has no bounds and isn't slowed down if you drag it to the edges:我的操纵杆代码,拖动有效但没有界限,如果将它拖动到边缘也不会减慢速度:
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()
}
}
Here is possible solution based on asymptotic curve (if somebody find it helpful).这是基于渐近曲线的可能解决方案(如果有人发现它有帮助)。
Tested with Xcode 11.4 / iOS 13.4使用 Xcode 11.4 / iOS 13.4 测试
Changed part更改部分
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
}
A guy on reddit helped me with this issue, I just had to change.gesture to this: reddit 上的一个人帮助我解决了这个问题,我只需要将其更改为:
.gesture(
DragGesture().onChanged { dragValue in
let translation: CGSize = dragValue.translation
let multiplier: CGFloat = 15
let incrementalW: CGFloat = log(abs(translation.width)) * multiplier
let incrementalH: CGFloat = log(abs(translation.height)) * multiplier
let incremental = CGSize(
width: translation.width > 0 ? incrementalW : -incrementalW,
height: translation.height > 0 ? incrementalH : -incrementalH
)
let resistance = CGSize(
width: abs(translation.width) < abs(incremental.width) ? translation.width : incremental.width,
height: abs(translation.height) < abs(incremental.height) ? translation.height : incremental.height
)
self.dragValue = resistance
self.isDragging = true
}
.onEnded { dragValue in
self.dragValue = .zero
self.isDragging = false
}
)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.