You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI中ViewThatFits引发动画异常问题求助

SwiftUI中ViewThatFits引发的过渡动画异常

问题描述

以下SwiftUI视图展示了一个由ViewThatFits导致的动画异常:

  • 复现步骤:渲染视图后,点击红色区域查看异常效果,点击蓝色区域查看无ViewThatFits时的正常效果
  • 异常表现:被ViewThatFits包裹的紫色视图,在触发.transition(.move(edge: .trailing))过渡时会瞬间跳转到目标位置,不遵循设置的动画;而绿色视图的过渡动画符合预期;移除ViewThatFits包裹后,紫色视图的动画恢复正常

复现代码

struct ViewThatFitsAnimationGlitchDemo: View {
    
    @State var displayedSubpage: Subpage? = nil
    
    enum Subpage {
        case normal
        case glitchy
    }
    
    var body: some View {
        VStack(spacing: 0) {
            tappableColor(.blue) {
                withAnimation {
                    displayedSubpage = .normal
                }
            }
            tappableColor(.red) {
                withAnimation {
                    displayedSubpage = .glitchy
                }
            }
        }
        .overlay {
            if let displayedSubpage {
                switch displayedSubpage {
                case .normal:
                    normalSubpage
                        .transition(.move(edge: .trailing))
                case .glitchy:
                    glitchySubpage
                        .transition(.move(edge: .trailing))
                }
            }
        }
    }
    
    var normalSubpage: some View {
        VStack(spacing: 0) {
            Color.purple
            tappableColor(.green) {
                withAnimation {
                    displayedSubpage = nil
                }
            }
        }
    }
    
    var glitchySubpage: some View {
        VStack(spacing: 0) {
            ViewThatFits {
                Color.purple
            }
            tappableColor(.green) {
                withAnimation {
                    displayedSubpage = nil
                }
            }
        }
    }
    
    func tappableColor(_ color: Color, onPressed: @escaping ()->()) -> some View {
        Button(action: onPressed) {
            color
        }
        .buttonStyle(.plain)
    }
}

临时解决方案

该问题源于ViewThatFits的布局尺寸计算逻辑与动画系统不兼容,导致过渡动画无法正确识别视图的起始和结束位置,可通过以下方式修复:

方法1:给ViewThatFits指定明确尺寸

为ViewThatFits添加全屏尺寸约束,让SwiftUI能正确获取布局信息,从而正常执行动画:

ViewThatFits {
    Color.purple
}
.frame(maxWidth: .infinity, maxHeight: .infinity)

方法2:移除不必要的ViewThatFits

如果场景中ViewThatFits仅包裹单个视图(如示例情况),直接移除ViewThatFits即可,此时它并未发挥自适应布局的作用。

内容的提问来源于stack exchange,提问作者jeremyabannister

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 05:07:24