swift - SwiftUI 链接动画
问题描述
我正在尝试做一些非常简单的事情。首先为填充设置动画,然后为宽度设置动画。
@state var animate = false
Rect().frame(width: animate ? 200 : 1, height: 2).animate(Animation.easeOut(duration: 0.5).delay(0.5)).padding(.bottom, animate ? 300 : 10).animate(.easeOut)
从这段代码中,我希望填充使用最外层的动画修改器,而框架使用内部的修改器。所以我希望填充首先动画,然后帧动画延迟,但他们都用最外层的动画制作动画。
我没有错吗?
更新:使用 Asperi 的异步方法后的工作解决方案
@State private var width: CGFloat = 0.1
@State private var isFirstResponder = false
private var becameFirstResponder: Binding<Bool> { Binding (
get: { self.isFirstResponder },
set: {
self.isFirstResponder = $0
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.width = self.isFirstResponder ? 240 : 0.1
}
}
)}
var body: some View {
Divider().frame(width: width, height: 2)
.animation(Animation.easeOut(duration: 1), value: width)
.background(Color.primary)
.padding(.bottom, keyboard.height).animate(.easeOut)
}
如您所见,此代码对于非常简单的链式动画来说太复杂了。有人在不使用 asyncAfter 的情况下得到解决方案吗?
解决方案
您延迟动画但同时更改两个值,这就是它感到困惑的原因。
这是可能的解决方案
struct DemoDelayedAnimations: View {
@State private var animate = false
// separate animatable values
@State private var width: CGFloat = 1
@State private var padding: CGFloat = 10
var body: some View {
VStack {
Rectangle()
.frame(width: width, height: 2)
.animation(.easeOut, value: width) // explicit to width
.padding(.bottom, padding)
.animation(.easeOut, value: padding) // explicit to padding
Divider()
Button("Go") {
self.padding = self.padding == 10 ? 300 : 10
// delay value change, not animation (it reacts on change)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.width = self.width == 1 ? 200 : 1
}
}
}
}
}
推荐阅读
- google-cloud-platform - GCP 负载平衡器运行状况检查无法正常工作
- javascript - 我被 daterangepicker 卡住了,我试图验证范围日期,它可以工作,但我在一个循环中
- virtual-machine - 一个 Kubernetes Pod 如何服务多个用户?
- ruby-on-rails - Capybara 什么时候没有在页面上找到内容?
- sql - 带有自定义模板的 SQL Server 事务
- css - 标题大小问题
- node.js - NodeJS在发送响应后返回错误
- php - 如何使用 PHP 中的参数在 SQL Server 中调用存储过程
- php - php,从一个大字符串中获取多个子字符串到一个数组中
- python - 将 python 参数传递到 MySQL