【问题标题】:SwiftUI: List is messing up animation for its subviews inside an HStackSwiftUI:List 在 HStack 中弄乱了其子视图的动画
【发布时间】:2021-01-07 03:49:05
【问题描述】:

我正在制作一个显示大量实时到达时间的 WatchOS 应用。我想在 List 的每个单元格的尾端放置一个视图,这是我设计的实时指示器。

实时指示器视图只有两个图像,它们的不透明度我正在连续设置动画。这个视图本身似乎工作正常:

animated view by itself

但是,当嵌入到 List 中然后嵌入到 HStack 中时,动画似乎不仅会影响动画视图的不透明度,还会影响动画视图的位置。

animated view inside a cell

这个视图行进的距离似乎只受 HStack 高度的影响。

动画视图代码:

struct RTIndicator: View {
    @State var isAnimating = true

    private var repeatingAnimation: Animation {
        Animation
            .spring()
            .repeatForever()
    } 

    private var delayedRepeatingAnimation: Animation {
        Animation
            .spring()
            .repeatForever()
            .delay(0.2)
    }

    var body: some View {
        ZStack {
            Image("rt-inner")
                .opacity(isAnimating ? 0.2 : 1)
                .animation(repeatingAnimation)
            Image("rt-outer")
                .opacity(isAnimating ? 0.2 : 1)
                .animation(delayedRepeatingAnimation)
        }
        .frame(width: 16, height: 16, alignment: .center)
        .colorMultiply(.red)
        .padding(.top, -6)
        .padding(.trailing, -12)
        .onAppear {
            self.isAnimating.toggle()
        }
    }
}

所有代码:

struct SwiftUIView: View {
    var body: some View {
        List {
            HStack {
                Text("Cell")
                    .frame(height: 100)
                Spacer()
                RTIndicator()
            }.padding(8)
        }
    }
}

【问题讨论】:

    标签: list animation swiftui opacity watchos


    【解决方案1】:

    虽然它很老套,但我找到了解决这个问题的临时方法。它基于 Asperi 的回答。

    我创建了一个名为 ClearView 的单独视图,它具有动画但不呈现任何视觉效果,并将其用作同一个 HStack 中的第二个整体。

    struct ClearView: View {
        @State var isAnimating = false
    
        var body: some View {
            Rectangle()
                .foregroundColor(.clear)
                .onAppear {
                    withAnimation(Animation.linear(duration: 0)) {
                        self.isAnimating = true
                    }
                }
        }
    }
    
    var body: some View {
        List {
            HStack {
                Text("Cell")
                    .frame(height: 100)
                Spacer()
            }
            .overlay(RTIndicator(), alignment: .trailing)
            .overlay(ClearView(), alignment: .trailing)
            .padding(8)
        }
    }
    

    【讨论】:

      【解决方案2】:

      这里找到了解决方法。使用 Xcode 12 测试。

      var body: some View {
          List {
              HStack {
                  Text("Cell")
                      .frame(height: 100)
                  Spacer()
              }
              .overlay(RTIndicator(), alignment: .trailing)  // << here !!
              .padding(8)
          }
      }
      

      【讨论】:

      • 这在预览中运行良好,但在模拟器中问题似乎仍然存在。
      猜你喜欢
      • 2022-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-19
      • 1970-01-01
      • 2015-04-12
      • 2013-09-07
      • 1970-01-01
      相关资源
      最近更新 更多