如何禁用SwiftUI中的.matchedGeometryEffect动画效果?
如何优雅禁用SwiftUI的.matchedGeometryEffect动画
你可以通过条件性应用修饰符或者利用系统无障碍环境变量来避免重复编写视图,以下是具体实现方式:
方法一:自定义条件修饰符
给View扩展一个带开关的matchedGeometryEffect,根据布尔值决定是否应用转场效果:
extension View { func matchedGeometryEffectIfEnabled<ID>( id: ID, in namespace: Namespace.ID, enabled: Bool, properties: MatchedGeometryProperties = .frame, anchor: UnitPoint = .center, isSource: Bool = true ) -> some View where ID: Hashable { Group { if enabled { self.matchedGeometryEffect( id: id, in: namespace, properties: properties, anchor: anchor, isSource: isSource ) } else { self } } } }
使用时直接传入控制开关(比如你的@AppStorage变量):
@AppStorage("enableMotionEffects") private var enableMotion = true @Namespace private var animationNamespace // 在视图中使用 YourView() .matchedGeometryEffectIfEnabled( id: "your-unique-id", in: animationNamespace, enabled: enableMotion )
方法二:结合系统减少动态效果环境变量
如果你的需求是跟随系统的「减少动态效果」设置,可以直接读取SwiftUI的环境变量,无需自定义开关:
@Environment(\.accessibilityReduceMotion) private var reduceMotion @Namespace private var animationNamespace // 在视图中使用 YourView() .matchedGeometryEffectIfEnabled( id: "your-unique-id", in: animationNamespace, enabled: !reduceMotion )
为什么之前的Transaction方法无效?
.matchedGeometryEffect不是Animation的内置类型,无法直接作为Transaction的动画参数传入。这种修饰符是通过视图关联实现转场的,而非依赖全局动画设置,所以最直接的控制方式就是条件性添加/移除它。
内容的提问来源于stack exchange,提问作者alanrick
相关产品推荐
相关产品推荐

