ios - SwiftUI - 如何覆盖嵌套的偏移/位置动画?

标签 ios swift swiftui swiftui-animation

考虑这个简单的例子:

struct TestView: View {
    @State private var enabled = false
    
    var body: some View {
        Circle()
            .foregroundColor(.red)
            .overlay(
                Circle()
                    .foregroundColor(.blue)
                    .frame(width: 50, height: 50)
                    .animation(.spring())
                
            )
            .frame(width: 100, height: 100)
            .offset(x: 0, y: enabled ? -50 : 50)
            .animation(.easeIn(duration: 1.0))
            .onTapGesture{
                enabled.toggle()
            }
            
    }
}
当点击生成的圆圈时,这会产生以下动画:
enter image description here
嵌套的圆用它自己的计时函数( Spring )动画到它的新全局位置,而外圆/父 View 用它的easieInOut 计时函数动画到新的全局位置。理想情况下,如果修饰符在父 View 抽象级别工作(在本例中为 offset ,但也有类似 position 之类的东西),则所有子项都将使用父项计时函数进行动画处理。
据推测,发生这种情况是因为 SwiftUI 渲染引擎在布局传递中为 View 层次结构中所有受影响的子项计算新的全局属性,并根据附加的最具体的动画修改器对每个属性的更改进行动画处理(即使在这种情况下,相对位置父级中的子级不会改变)。这使得在 View 的 subview 可能有自己复杂的动画运行时(父 View 不知道也不应该知道),做一些像正确翻译 View 这样简单的事情变得非常困难。
我注意到的另一个怪癖是,在这个特定的例子中,添加一个 animation(nil)尽管 .easeInOut,在偏移修饰符之前的修饰符会中断外圆上的动画。保留直接附加到偏移修改器。这违反了我对这些修改器如何链接的理解,其中(根据 this source )动画修改器适用于它需要的所有 View ,直到下一个嵌套的动画修改器。

最佳答案

这对我来说似乎是一个错误,可能值得向 Apple 报告。我确实找到了一个奇怪的解决方法,通过在 .offset 修饰符之前添加另一个修饰符:

struct TestView: View {
    @State private var enabled = false
    
    var body: some View {
        Circle()
            .foregroundColor(.red)
            .overlay(
                Circle()
                    .foregroundColor(.blue)
                    .frame(width: 50, height: 50)
                    .animation(.spring())
                
            )
            .frame(width: 100, height: 100)
            .scaleEffect(1) // <------- this doesn't do anything but somehow overrides the animation
            .offset(x: 0, y: enabled ? -50 : 50)
            .animation(.easeIn(duration: 1.0))
            .onTapGesture{
                enabled.toggle()
            }
            
    }
}
我已经尝试过使用 scaleEffect、rotationEffect 和 rotation3DEffect,它们都有效。并非所有修饰符都有效。我真的很好奇为什么这些特定的会这样做。
.animation(nil) 对我来说似乎也是一个错误。

关于ios - SwiftUI - 如何覆盖嵌套的偏移/位置动画?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65544581/

相关文章:

ios - HLS 冗余流和不良网络导致 AVPlayer 行为奇怪

ios - 选择 UITableView 上的所有单元格

swiftui - SidebarListStyle 不再显示折叠/展开按钮 - Xcode 15 beta 6

ios - 如何在 SwiftUI 中关闭选项卡 View Root View 的呈现 View ?

swift - 需要帮助使 iOS 14 Widget 显示来自 REST api 的内容

ios - React native - Webview 视频在父状态更改时重新加载

ios - 使用 CoreData 在两个队列之间传递对象引用的最佳实践是什么?

ios - 为 Debug-iphoneos 构建时如何调试断言

swift - 如何为 CGpath 数组的绘制设置动画?

swift - 我怎样才能实现和搜索过滤器