繁体   English   中英

SwiftUI 中@GestureState 的显式动画

[英]Explicit animation of @GestureState in SwiftUI

我学习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)
}

}

不幸的是,我遇到了两个问题。

  1. dragState设置回初始.inactive值时,更改不会动画化:

屏幕录制:dragState 重置

  1. 当手势序列被突然打断时,影子的行为很奇怪:

屏幕录制:中断手势

任何想法如何解决这一问题? 先感谢您。

我最终使用了有条件设置的隐式动画,如下所示:

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)

它解决了这两个问题。 但是,如果有人可以向我展示如何明确地做到这一点,我仍然想知道。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM