SwiftUI动画视图出现在ZStack中时出现奇怪的过渡

Posted

技术标签:

【中文标题】SwiftUI动画视图出现在ZStack中时出现奇怪的过渡【英文标题】:SwiftUI animated view weird transition when appears inside ZStack 【发布时间】:2021-03-01 12:22:48 【问题描述】:

我对动画加载视图的行为有疑问。网络调用时会显示加载视图。我的 viewModel 中有一个 isLoading @Published var,ActivityIndi​​cator 显示在我的视图中的 ZStack 中。 Activityindicator 是一个自定义视图,我在其中制作了一个修剪过的圆圈的动画 - 旋转它。每当活动指示器显示在我的 mainView 中时,它就会出现奇怪的过渡 - 它从左上角过渡到视图的中心。有谁知道为什么会这样?我附上带有代码的结构和带有行为的 3 张图片。 活动指标:

struct OrangeActivityIndicator: View 
    var style = StrokeStyle(lineWidth: 6, lineCap: .round)
    @State var animate = false
    let orangeColor = Color.orOrangeColor
    let orangeColorOpaque = Color.orOrangeColor.opacity(0.5)
    
    init(lineWidth: CGFloat = 6) 
        style.lineWidth = lineWidth
    
    
    var body: some View 
        ZStack 
            CircleView(animate: $animate, firstGradientColor: orangeColor, secondGradientColor: orangeColorOpaque, style: style)
        .onAppear() 
            self.animate.toggle()
        
    


struct CircleView: View 
    @Binding var animate: Bool
    var firstGradientColor: Color
    var secondGradientColor: Color
    var style: StrokeStyle
    
    var body: some View 
        Circle()
            .trim(from: 0, to: 0.7)
            .stroke(
                AngularGradient(gradient: .init(colors: [firstGradientColor, secondGradientColor]), center: .center), style: style
            )
            .rotationEffect(Angle(degrees: animate ? 360 : 0))
            .transition(.opacity)
            .animation(Animation.linear(duration: 0.7) .repeatForever(autoreverses: false), value: animate)
    

视图在:

struct UserProfileView: View 
    @ObservedObject var viewModel: UserProfileViewModel
    @Binding var lightMode: ColorScheme

    var body: some View 
        NavigationView 
            ZStack 
                VStack(alignment: .center, spacing: 12) 
                    HStack 
                        Text(userProfileEmail)
                            .font(.headline)
                            .foregroundColor(Color(UIColor.label))
                        Spacer()
                    .padding(.bottom, 16)
                    SettingsView(userProfile: $viewModel.userProfile, isDarkMode: $viewModel.isDarkMode, lightMode: $lightMode, location: viewModel.locationManager.address, viewModel: viewModel)
                    ButtonsView( userProfile: $viewModel.userProfile)
                    Spacer()

                .padding([.leading, .trailing], 12)

                if viewModel.isLoading 
                    OrangeActivityIndicator()
                        .frame(width: 40, height: 40)
//                        .animation(nil)
                
            
        
    

我也尝试过使用动画 nil,但它似乎不起作用。 以下是图片:

【问题讨论】:

尝试在 VStack 和 ZStack(alignment: .topLeading) 之前将带有 maxWidth 和 maxHeight 的明确 Rectangle() 设置为 .infinity(alignment: .topLeading) ZStack(alignment: .topLeading) Rectangle() .frame(maxWidth: .infinity, maxHeight: .infinity) .background(Color.clear) VStack(alignment: .center, 间距: 12) .... if viewModel.isLoading OrangeActivityIndi​​cator() .frame(width: 40, height: 40) .animation(nil) 我试过了,它不起作用 它是这样工作的? 没有。正如你所说,我在 ZStack 主体中的 VStack 之前添加了一个带有 maxWidth 和 maxHeight 框架的 .infinity 和背景 Color.clear 的 Rectangle 。和 ZStack 对齐 topLeading。它不起作用:( 【参考方案1】:

这是一个可能的解决方案 - 把它 NavigationView。使用 Xcode 12.4 / ios 14.4 测试

    NavigationView 

       // .. your content here

    
    .overlay(                    // << here !!
        VStack 
            if isLoading 
                OrangeActivityIndicator()
                    .frame(width: 40, height: 40)
            
        
    )

【讨论】:

什么都没有改变,我有同样的行为。 :( 不错!天哪,我几天来一直在寻找解决方案。谢谢你。请告诉我为什么会出现这个错误?

以上是关于SwiftUI动画视图出现在ZStack中时出现奇怪的过渡的主要内容,如果未能解决你的问题,请参考以下文章

出现 SwiftUI 意外动画

如何通过拖动在SwiftUI ZStack中重新排列视图

如何阻止视图在 SwiftUI 中出现动画?

ScrollView 的 SwiftUI 动画

SwiftUI:动画过渡

SwiftUI onAppear:动画持续时间被忽略