破碎的动画SwiftUI

Posted

技术标签:

【中文标题】破碎的动画SwiftUI【英文标题】:Broken Animation SwiftUI 【发布时间】:2020-02-29 10:25:54 【问题描述】:

我最初有这个问题here。 @arsenius 提出的解决方案适用于这个玩具示例。然而,我的应用程序更复杂,我花了很长时间才找出动画中断的地方。在示例中,我使用了两个动​​画HStack。但是,如果我将这些 HStack 替换为 两个不同的 (!) 自定义视图,动画就会再次损坏。

代码如下:

class State:ObservableObject
    @Published var showSolution = false


struct ContentView: View 
    @EnvironmentObject var state:State

    var body:some View 
        VStack 
            if state.showSolution
                CustomToggleOne()
                    .background(Color.red)
                    .id("one")
                    .animation(Animation.default)
                    .transition(.slide)
             else 
                CustomToggleTwo()
                    .background(Color.yellow)
                    .id("two")
                    .animation(Animation.default.delay(2))
                    .transition(.slide)
            
        
    


struct CustomToggleOne: View
    @EnvironmentObject var state:State

    var body:some View
        HStack
            Spacer()
            Button(action:
                withAnimation 
                    self.state.showSolution.toggle()
                
            )
                Text("Next")
            .padding()
            Spacer()
        
    


struct CustomToggleTwo: View
    @EnvironmentObject var state:State

    var body:some View
        HStack
            Spacer()
            Button(action:
                withAnimation 
                    self.state.showSolution.toggle()
                
            )
                Text("Next")
            .padding()
            Spacer()
        
    


我将State 的一个实例添加到SceneDelegate.swift 中的ContentView 作为EnvironmentObject,如下所示:

let contentView = ContentView().environment(\.managedObjectContext, context).environmentObject(State())

当我们在ContentView 中使用两次CustomToggleOne() 而不是CustomToggleTwo() 时,可以看到预期的动画。

【问题讨论】:

【参考方案1】:

这是正确的方法,下面和 cmets 中的一些解释。使用 Xcode 11.2 / ios 13.2 测试

提醒:不要在预览中测试过渡 - 仅在模拟器或设备上

// !! Don't name your types as API,
// State is SwiftUI type, might got unpredictable weird issues
class SolutionState:ObservableObject
    @Published var showSolution = false


struct TestBrokenAnimation: View 
    @EnvironmentObject var state:SolutionState

    var body:some View 
        VStack 
            if state.showSolution
                CustomToggleOne()
                    .background(Color.red)
                    .id("one")
                    .transition(.slide) // implicit animations confuse transition, don't use it
             else 
                CustomToggleTwo()
                    .background(Color.yellow)
                    .id("two")
                    .transition(.slide)
            
        
    

public func withAnimation<Result>(_ animation: Animation? = .default, 
              _ body: () throws -> Result) rethrows -> Result

正如它所看到的withAnimation 不是状态,它只是激活通过修饰符定义的动画,它显式应用指定的动画,拥有,所以在修饰符中添加更多肯定会导致一些冲突。

所以使用带有过渡的显式动画。

struct CustomToggleOne: View
    @EnvironmentObject var state:SolutionState

    var body:some View
        HStack
            Spacer()
            Button(action:
                withAnimation(Animation.default.delay(2)) 
                    self.state.showSolution.toggle()
                
            )
                Text("Next")
            .padding()
            Spacer()
        
    


struct CustomToggleTwo: View
    @EnvironmentObject var state:SolutionState

    var body:some View
        HStack
            Spacer()
            Button(action:
                withAnimation() 
                    self.state.showSolution.toggle()
                
            )
                Text("Next")
            .padding()
            Spacer()
        
    

【讨论】:

以上是关于破碎的动画SwiftUI的主要内容,如果未能解决你的问题,请参考以下文章

什么时候设置更改 heightForRowAt UITableView 动画被破坏

【UE】Chaos破碎方案浅析

求助 WOW刷破碎10分钟跳一下的插件或者方法

如何在 Unity 中重新加入破碎的对象?

顶板破碎注浆加固材料的配置及性能测试

《破碎的残阳,我们逆光》连载小说- HashMap剖析