如何在 SwiftUI 中使视图的高度从 0 动画到高度?
Posted
技术标签:
【中文标题】如何在 SwiftUI 中使视图的高度从 0 动画到高度?【英文标题】:How to make a view's height animate from 0 to height in SwiftUI? 【发布时间】:2021-01-06 01:25:53 【问题描述】:我想让这个条形图的高度(较大条形图的一部分)在从 0 到其给定高度的动画上显示,但我在 SwiftUI 中无法完全弄清楚?我发现这段代码很有帮助,但只有第一条(共 7 个)动画:
struct BarChartItem: View
var value: Int
var dayText: String
var topOfSCaleColorIsRed: Bool
@State var growMore: CGFloat = 0
@State var showMore: Double = 0
var body: some View
VStack
Text("\(value)%")
.font(Font.footnote.monospacedDigit())
RoundedRectangle(cornerRadius: 5.0)
.fill(getBarColor())
.frame(width: 40, height: growMore)
.onAppear
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5)
withAnimation(.linear(duration: 7.0))
growMore = CGFloat(value)
showMore = 1
.opacity(showMore)
Text(dayText.uppercased())
.font(.caption)
这是图表:
HStack(alignment: .bottom)
ForEach(pastRecoveryScoreObjects) pastRecoveryScoreObject in
BarChartItem(value: pastRecoveryScoreObject.recoveryScore, dayText: "\(pastRecoveryScoreObject.date.weekdayName)", topOfSCaleColorIsRed: false)
【问题讨论】:
你其他酒吧的代码是什么? @aheze 请在底部查看我的补充 【参考方案1】:这很有效:您可以获取 ForEach 循环的索引并将每个条形的动画延迟一段时间 * 该索引。所有的条都通过绑定连接到同一个状态变量,并且状态在出现时立即设置。您可以根据自己的喜好调整参数。
struct TestChartAnimationView: View
let values = [200, 120, 120, 90, 10, 80]
@State var open = false
var animationTime: Double = 0.25
var body: some View
VStack
Spacer()
HStack(alignment: .bottom)
ForEach(values.indices, id: \.self) index in
BarChartItem(open: $open, value: values[index])
.animation(
Animation.linear(duration: animationTime).delay(animationTime * Double(index))
)
.onAppear
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5)
open = true
struct BarChartItem: View
@Binding var open: Bool
var value: Int
var body: some View
VStack
Text("\(value)%")
.font(Font.footnote.monospacedDigit())
RoundedRectangle(cornerRadius: 5.0)
.fill(Color.blue)
.frame(width: 20, height: open ? CGFloat(value) : 0)
Text("Week".uppercased())
.font(.caption)
【讨论】:
谢谢!这很好用,除了视图是自上而下构建的,有没有办法让它们自下而上增长? 当我运行它时,它们是从下到上的,因为我把它们放在一个带有垫片的 vstack 中。如果您想要相反的方向,请尝试移动下面的垫片 ? 我确实尝试过在任一侧使用 vstack 和 spacer 但结果相同,无法弄清楚为什么它的行为会有所不同,因为我们的代码似乎相同?♂️【参考方案2】:编辑:ForEach 动画有点奇怪。我不知道为什么,但这有效:
struct ContentView: View
let values = [200, 120, 120, 90, 10, 80]
var body: some View
HStack(alignment: .bottom)
ForEach(values, id: \.self) value in
BarChartItem(totalValue: value)
.animation(.linear(duration: 3))
struct BarChartItem: View
@State var value: Int = 0
var totalValue = 0
var body: some View
VStack
Text("\(value)%")
.font(Font.footnote.monospacedDigit())
RoundedRectangle(cornerRadius: 5.0)
.fill(Color.blue)
.frame(width: 20, height: CGFloat(value))
Text("Week".uppercased())
.font(.caption)
.onAppear
value = totalValue
我没有在onAppear
中应用动画,而是在ForEach
中应用了一个隐式动画。
结果:
【讨论】:
谢谢,但我正在尝试显示动画,以便图表中的每个条从屏幕底部依次动画到顶部。 对不起,如果我不清楚,很难说清楚,但可以想象出现的图形,从底部开始,第一个条将增长到它的高度,然后是下一个条,直到所有条都增长到他们的身高。与其从中间开始然后向上和向下增长(就像在你的动画中那样),它们应该从最底部开始并且只会向上增长。 啊,也有点像一本吧? @bze12 的回答可能有效以上是关于如何在 SwiftUI 中使视图的高度从 0 动画到高度?的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI中应用Hero动画(Hero Animation)时一些需要填的坑
SwiftUI中应用Hero动画(Hero Animation)时一些需要填的坑
SwiftUI - 在列表中的视图内触发的动画也不会为列表设置动画
如何防止工作表在 SwiftUI 中使其后面的视图变暗或删除不必要的填充?