ios - SwiftUI 中 @GestureState 的显式动画
问题描述
我正在学习 SwiftUI 作为一种爱好,我正在尝试使用@GestureState
如下所示创建一个可拖动的矩形视图。当视图被拖动时,我想为角和阴影半径的变化设置动画。Apple 文档中的示例对阴影部分使用了隐式动画,并删除了偏移修改器上方的所有动画。但是,因为我还想为圆角半径设置动画,所以我认为我需要明确地进行。这是我的第一次尝试:
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)
}
}
不幸的是,我遇到了两个问题。
- 当
dragState
设置回初始.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)
.animation(dragState.isDragging ? nil : .easeInOut(duration: minDuration))
.gesture(longPressThenDrag)
它解决了这两个问题。但是,如果有人可以明确地告诉我如何做到这一点,我仍然想知道。
推荐阅读
- angular - 使用 ngModel 处理模型更改
- mysql - 将mysql ddl和表数据导出到aws redshift的最佳方法是什么?
- c - 如何修复'第 1 行:语法错误:单词意外(期望“)”)'
- javascript - 保持身份验证状态 Firebase + Chrome 扩展
- javascript - 在 dom 元素上读取 css 转换矩阵会给出相互冲突的值
- javascript - exit().remove() 不在视野范围内时不会删除节点
- python - 如何更改 pandas df 中的日期时间值?
- c# - 如何在列表中存储、排序整数(来自用户的输入)?
- android - 如何以编程方式相对于 ConstraintLayout 中的另一个视图设置视图的宽度/边距
- javascript - 我需要将图像放置在背景图像的底部,并在调整窗口大小时让它们保持原位