iOS 14.5 SwiftUI长按手势取消时动画异常问题求解
问题成因
- 你在
LongPressGesture的updating闭包中给全局transaction设置了固定2秒的线性动画,这个动画会作用于所有因isDetectingLongPress状态变化触发的视图更新,包括手势中途取消时的状态回置过程。 - 当你未达到最小长按时长就抬手时,
@GestureState会自动立刻重置为初始值false,此时进度条从当前已展开的中间宽度缩回至5px,仍然套用了2秒的线性动画,同时你没有为进度条的宽度变化显式绑定状态对应的动画规则,导致宽度收缩和位置计算出现异常偏移。 - 额外的隐式动画冲突:你给下方的白色方块加了未绑定指定状态的全局
.animation(.easeIn(duration: 0.2))修饰符,会干扰同层级其他视图的动画逻辑。
解决方案
核心修改逻辑:
- 给白色方块的动画显式绑定
completedLongPress状态,避免全局动画干扰 - 为进度条的宽度变化单独显式绑定
isDetectingLongPress状态的动画,手势取消时用短时长动画快速缩回 - 移除
updating闭包中全局transaction的动画设置,避免全局动画污染
修复后代码如下:
struct DiamondPress: View { @GestureState var isDetectingLongPress = false @State var completedLongPress = false var longPress: some Gesture { LongPressGesture(minimumDuration: 2) .updating($isDetectingLongPress) { currentState, gestureState, transaction in gestureState = currentState } .onEnded { _ in self.completedLongPress.toggle() } } var body: some View { ZStack { Color.offWhite RoundedRectangle(cornerRadius: 12, style: .continuous) .frame(width: 100, height: 100, alignment: .center) .foregroundColor(.white) .scaleEffect(completedLongPress ? 2.0 : 1.0) .gesture(longPress) // 动画显式绑定对应状态,避免全局干扰 .animation(.easeIn(duration: 0.2), value: completedLongPress) // 红色进度条 Rectangle() .frame( width: isDetectingLongPress ? 100 : 5, height: 5, alignment: .center ) .foregroundColor(.red) // 显式绑定状态对应动画:按下时2秒线性展开,取消/结束时0.2秒快速缩回 .animation(.linear(duration: isDetectingLongPress ? 2 : 0.2), value: isDetectingLongPress) } .edgesIgnoringSafeArea(.all) } }
内容的提问来源于stack exchange,提问作者nevrx
相关产品推荐
相关产品推荐

