[英]Explicit animation of @GestureState in SwiftUI
I am learning SwiftUI as a hobby and I am trying to create a draggable rectangular view using @GestureState
as shown here .我学习SwiftUI作为一种业余爱好,我试图创建使用拖动矩形视图@GestureState
如图所示这里。 When the view is being dragged I want to animate a change in corner and shadow radius.当视图被拖动时,我想为角和阴影半径的变化设置动画。 The example in Apple Documentation uses implicit animations for the shadow part and removes any animations above the offset modifier. Apple 文档中的示例为阴影部分使用了隐式动画,并删除了偏移修改器上方的任何动画。 However, because I also want to animate the corner radius, I think I need to do it explicitly.但是,因为我也想为圆角半径设置动画,所以我想我需要明确地做这件事。 This is my first try:这是我的第一次尝试:
struct DraggableView: View {
enum DragState {
case inactive
case pressing
case dragging(translation: CGSize)
var translation: CGSize {
switch self {
case .inactive, .pressing:
return .zero
case .dragging(let translation):
return translation
}
}
var isActive: Bool {
switch self {
case .inactive:
return false
case .pressing, .dragging:
return true
}
}
var isDragging: Bool {
switch self {
case .inactive, .pressing:
return false
case .dragging:
return true
}
}
}
@GestureState var dragState = DragState.inactive
var body: some View {
let minDuration = 0.5
let longPressThenDrag = LongPressGesture(minimumDuration: minDuration)
.sequenced(before: DragGesture())
.updating($dragState) { value, state, transaction in
transaction.animation = .easeInOut(duration: minDuration)
switch value {
case .first(true): // Long press begins
state = .pressing
case .second(true, let drag): // Dragging begins
transaction.animation = nil // Do not animate translation update
state = .dragging(translation: drag?.translation ?? .zero)
default:
state = .inactive
}
}
return RoundedRectangle(cornerRadius: dragState.isActive ? 25 : 0)
.frame(height: 150)
.foregroundColor(.blue)
.offset(
x: dragState.translation.width,
y: dragState.translation.height
)
.shadow(radius: dragState.isActive ? 25 : 0)
.gesture(longPressThenDrag)
}
} }
Unfortunately there are two issues I am stuck with.不幸的是,我遇到了两个问题。
dragState
is set back to the initial .inactive
value the changes are not animated:当dragState
设置回初始.inactive
值时,更改不会动画化:Screen recording: dragState reset屏幕录制:dragState 重置
Screen recording: interrupted gesture屏幕录制:中断手势
Any ideas how to fix this?任何想法如何解决这一问题? Thank you in advance.先感谢您。
I ended up using conditionally set implicit animations like this:我最终使用了有条件设置的隐式动画,如下所示:
return RoundedRectangle(cornerRadius: dragState.isActive ? 25 : 0)
.frame(height: 150)
.foregroundColor(.blue)
.offset(
x: dragState.translation.width,
y: dragState.translation.height
)
.shadow(radius: dragState.isActive ? 25 : 0)
.animation(dragState.isDragging ? nil : .easeInOut(duration: minDuration))
.gesture(longPressThenDrag)
It solves the two issues.它解决了这两个问题。 But if anyone can show me how to do it explicitly I'd still like to know.但是,如果有人可以向我展示如何明确地做到这一点,我仍然想知道。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.