ios - SwiftUI 中 @GestureState 的显式动画

标签 ios swift animation swiftui gesture-state

我正在学习 SwiftUI 作为一种爱好,我正在尝试使用 @GestureState 创建一个可拖动的矩形 View ,如图 here 。当拖动 View 时,我想对角和阴影半径的变化进行动画处理。 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 值时,更改不会产生动画效果:

Screen recording: dragState reset

  • 当手势序列突然中断时,阴影会表现得很奇怪:
  • Screen recording: interrupted gesture

    有什么想法可以解决这个问题吗?预先感谢您。

    最佳答案

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

    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)
    

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

    关于ios - SwiftUI 中 @GestureState 的显式动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63943596/

    相关文章:

    ios - 如何在纵向应用程序中录制横向视频? ( swift 2,iPhone)

    swift - 保留类和结构之间的循环

    c# - 在Unity中制作无尽的戒指视觉效果

    iPhone应用程序将对象数组作为无法识别的参数传递给.net SOAP Web服务

    ios - XCFramework 与其他第 3 方依赖项

    ios - 键盘破坏了 UICollectionView 的单元格

    iOS : unsigned long with big factorial

    xcode - 字典在结构 SWIFT 中不起作用

    javascript - 如何植入这样的led动画?

    animation - 如何在预定义容器中包含 D3 动画的元素?