swift - 带有数组的 SwiftUI 动画形状
问题描述
我正在尝试为从对象数组中的数据派生的 SwiftUI 中的自定义形状设置动画。我创建了这个示例来说明我在尝试使其正常工作时遇到的问题。
在这个简单的例子中。拖动红点后,它会通过弹簧动画偏移其 X 和 Y。但是,形状会捕捉到新位置,而不是使用点平滑动画。
我已经尝试了几个版本,animatableData
但仍然无法让动画正常工作。希望对此有更多了解的人可以提供帮助!谢谢你。
final class Item: Identifiable {
let id: String
var position: CGPoint
let radius: CGFloat = 10
var offset: CGSize {
CGSize(width: position.x-radius, height: position.y-radius)
}
init(id: String, position: CGPoint) {
self.id = id
self.position = position
}
}
final class Manager: ObservableObject {
var items = [
Item(id: "Item 1", position: .init(x: 50, y: 200)),
Item(id: "Item 2", position: .init(x: 200, y: 200)),
Item(id: "Item 3", position: .init(x: 200, y: 50))
]
}
struct CustomShape: Shape {
@ObservedObject var manager: Manager
var animatableData: [Item] {
get { manager.items }
set { manager.items = newValue }
}
func path(in rect: CGRect) -> Path {
Path { path in
for i in 0..<animatableData.count {
let item = animatableData[i]
if i == 0 {
path.move(to: item.position)
} else {
path.addLine(to: item.position)
}
}
}
}
}
struct ContentView: View {
@ObservedObject var manager = Manager()
var body: some View {
ZStack(alignment: .topLeading) {
CustomShape(manager: manager)
ForEach(manager.items) { item in
Circle().foregroundColor(.red)
.frame(width: item.radius*2, height: item.radius*2)
.offset(item.offset)
.gesture(
DragGesture()
.onChanged { gesture in
manager.objectWillChange.send()
item.position = gesture.location
}
.onEnded { gesture in
withAnimation(.spring()) {
manager.objectWillChange.send()
item.position = CGPoint(
x: item.position.x + 20,
y: item.position.y + 20
)
}
}
)
}
}
}
}
解决方案
您自己指定的项目animatableData
必须是可动画的,即符合Animatable
协议。这包括CGPoint
s、CGRect
s、CGSize
s 和其他一些类型。要么,要么他们必须符合协议VectorArithmetic
,这也包括Float
s,CGFloat
s和Double
s。如果您在 GitHub 上搜索“animatableData”,您应该能够找到各种示例。
推荐阅读
- javascript - Ionic/Angular Square 网络支付
- kotlin - Mockk 将重载函数与泛型匹配
- javascript - 通用联合类型的打字稿错误:'不可分配给类型'
- javascript - 如何让 Object.keys 遍历数组对象以在每次迭代结束时等待异步获取的 api 结果?
- rust - 在内部创建 tokio::runtime 的应用程序的异步集成测试失败,并显示“无法在运行时内启动运行时”
- python - 在 pandas 和 numpy 中构建具有多条件的新列
- android - 电子邮件和密码身份验证在 Android Studio 上不可见
- javascript - 西里尔文中的 \b 问题(JavaScript 正则表达式)
- java - 反编译 MinecraftForge 1.8.9 时出现 Java“peer not authenticated”错误
- c++ - 这两个字符串流之间的区别?