SwiftUI:List正在弄乱HStack中其子视图的动画

时间:2020-09-21 03:07:57

标签: list animation swiftui opacity watchos

我正在制作一个WatchOS应用程序,该应用程序显示大量实时到达时间。我想将一个视图(我设计的实时指示器)放置在将连续进行动画处理的List的每个单元的尾部。

实时指示器视图仅包含两张图像,我正在对其进行不连续动画处理。此视图本身似乎运行良好:

animated view by itself

但是,当将其嵌入到列表中然后再嵌入到HStack中时,该动画似乎不仅影响其动画视图的不透明度,而且还影响着动画视图的位置。

animated view inside a cell

此视图行进的距离似乎仅受HStack高度的影响。

动画视图代码:

[
  {
    $unwind: "$books"
  },
  {
    $match: {
      "books.pages": {
        $gt: 21
      }
    }
  },
  {
    $sort: {
      "books.released": 1
    }
  },
  {
    $group: {
      _id: null,
      "books": {
        $push: "$books"
      }
    }
  }
]

所有代码:

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()
        }
    }
}

2 个答案:

答案 0 :(得分:0)

在这里找到解决方法。经过Xcode 12测试。

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

答案 1 :(得分:0)

尽管它很hacky,但我已经找到了解决此问题的临时方法。它基于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)
    }
}