首页 > 解决方案 > 如何在 SwiftUI 中禁用子视图上的特定状态更改动画

问题描述

我的ContentView包含一个视图(MapCardView),该视图(mapcardview)在启动时被推到可见区域外,并在映射视图(MapKitView)上的注释(非常类似于地图中的地图上的注释)时从底部向下滑动(与其子视图一起)。应用程序):

@State private var showAnnotationCard = false
@State private var annotation: MKAnnotation?
private let kBottomCardPosition: CGFloat = -150

var body: some View {
    
        ZStack {
            
            MapKitView(isAnnotationSelected: $showAnnotationCard, selectedAnnotation: $annotation)
                .edgesIgnoringSafeArea(.all)
        
            MapCardView(annotation: $annotation)
                .edgesIgnoringSafeArea(.bottom)
                .offset(y: (bounds.size.height + bounds.safeAreaInsets.bottom)) //Push the view off the screen on launch
                .offset(y: showAnnotationCard ? kBottomCardPosition : 0) //Push the view back into the visible area if an annotation is selected
                .animation(.spring()) //Animate the change of the offset for the "sliding" effect
                
        }
    }
    
}

struct MapCardView: View {

    @Binding var annotation: MKAnnotation?

    var body: some View {
    
        VStack {
           
            HStack {
                VStack(alignment: .leading) {
                    
                    Text((annotation?.title ?? "") ?? "")
                        .font(.title2).bold()
                    
                    Text((annotation?.subtitle ?? "") ?? "")
                        .font(.caption)
                }
                
                Spacer()
                
            }
            .padding(.leading)
            
            Spacer()
        }
        .frame(maxWidth: .infinity)
        
    }
}

在 MapCardView 仍然可见时在地图视图上选择不同的注释将导致文本视图(显示注释的标题和副标题)动画内容更改,如果后续文本内容占用的宽度比前一个更大。我不想看到文本更改被动画化,而是让它在没有动画的情况下立即显示。

通过在有问题的文本视图上使用.animation(nil),这些视图也将停止滑动,而是立即出现和消失,这不是想要的行为。是否可以单独排除内容更改的动画,或者我是否必须完全改变我为超级视图设置动画的方式,并对我的动画内容进行更多限制?

更新 感谢@Asperi的回答,将动画限制为仅观察 showAnnotationCard 状态的变化确实阻止了文本在屏幕上对其宽度进行动画更改。但是,当第一次通过选择注释拉起卡片时,它仍然显示文本更改动画。

标签: swiftswiftui

解决方案


尝试限制状态值的动画

MapCardView(annotation: $annotation)
    .edgesIgnoringSafeArea(.bottom)
    .offset(y: (bounds.size.height + bounds.safeAreaInsets.bottom))
    .offset(y: showAnnotationCard ? kBottomCardPosition : 0)
    .animation(.spring(), value: showAnnotationCard)           // << here !!

推荐阅读