SwiftUI 动画如何与子视图隔离?

Posted

技术标签:

【中文标题】SwiftUI 动画如何与子视图隔离?【英文标题】:How can SwiftUI animations be isolated to child views? 【发布时间】:2021-02-15 21:43:14 【问题描述】:

我正在尝试为网格视图的单元格内的转换设置动画,但我不希望此动画影响单元格的布局,因为它们会因数据更改而重新定位。我觉得这应该很简单,但无论我尝试什么都行不通。

也许有人可以演示 SwiftUI,其中网格视图中的单元格可以在没有弹簧动画的情况下重新排序,而单元格使用弹簧动画在本地调整大小?那将不胜感激!

var body: some View 
  LazyVGrid(columns) 
    ForEach(dataSource.dataList)  // This is an array of structs
      CellView(data: $0)
    
  
  .animation(.default)



struct CellView: View 
  let data: CellData
  @State var contentScale: CGFloat = 1

  init(data: CellData) 
    self.data = data
    let anim = Animation.interpolatingSpring(stiffness: 50, damping: 5)
    withAnimation(anim) 
        self.contentScale = calcScaleFrom(data: data)
    
  

  var body: some View 
     // Configure cell with data
     // and animate scale based on data properties
  

【问题讨论】:

我猜你的网格上有一个修饰符或带有 .animation() 的地方。这会为影响组件的所有事件添加动画。相反,请移除该修饰符,并在导致动画的操作周围使用 withAnimation。 @nicksarno 好主意!我仍在使用 SwiftUI 学习动画,但这听起来会奏效! 如果你有兴趣,我在 YouTube 上有一个视频解释这个:) youtu.be/0WY-wrW2_bs 好吧,我理解你的教程,但我仍然在努力寻找一种方法来使用 withAnimation 来获得每次我的单元格被网格视图的主体“重建”时都会重新创建的状态... ForEach(dataList) CellView(data: $0) 基本上我希望在数据列表更改时使用一个动画,当数据列表中元素的属性发生更改时使用一个动画...:T 【参考方案1】:

好的,我没有找到确切问题的答案……但我确实找到了解决方法。我的确切目标是让我的单元格使用弹簧动画更新它们的 content,但让网格使用默认动画重新排列单元格。为此,我只是在网格的数据模型代码中添加了一个withAnimation 块,它根据数据列表是否更改顺序来选择动画样式!

    @Published var currentList: [CellData]

    func updateData() 
      let newList = ...
      let anim: Animation
      if newList.map($0.id).elementsEqual(currentList.map($0.id)) 
        // Data may have changed but does not require any cell reordering
        anim = Animation.interpolatingSpring(stiffness: 80, damping: 5)
       else 
        // Cells will change order!
        anim = .default
      
      withAnimation(anim) 
        currentList = newList
      
    

【讨论】:

以上是关于SwiftUI 动画如何与子视图隔离?的主要内容,如果未能解决你的问题,请参考以下文章

UIView 动画与子视图同步

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

SwiftUI之深入解析如何定制视图的动画和转场

SwiftUI 如何临时为视图颜色的前景颜色设置动画?

SwiftUI如何模拟视图发光增大的动画效果

SwiftUI如何模拟视图发光增大的动画效果