突然间,我发现其中没有一个没有自动动画:
没有用于插入、删除、重新排序等的动画。☹️ Id
s在转换之间是唯一且持久的
问题 1
我怎样才能让它们按预期工作?
问题2
有没有一种简单的方法来制作动画来查看列表之间的过渡?就像在单个列表的各个部分之间移动一行一样。
解释:
假设我有三个列表,它们将单个数组的元素的不同状态分组:
extension Call {
enum State: Equatable {
case inProgress
case accepted
case rejected
}
}
可观察的:
class CallManager: ObservableObject {
@Published var calls: [Call]
init(visits: [Call] = []) { self.calls = visits }
}
Call 是一个简单的 Identifiable:
struct Call: Identifiable & Equatable & Hashable {
let id = UUID()
var state: State
}
通过进行这些绑定,我将所有列表绑定到核心calls
数组:
extension CallManager {
func bindingCalls(for state: Call.State) -> Binding<[Call]> {
Binding<[Call]>(
get: { self.calls.filter { $0.state == state } },
set: { // TODO: Find a better way for this
self.calls.removeAll(where: { $0.state == state })
self.calls.append(contentsOf: $0)
}
)
}
var inProgress: Binding<[Call]> { bindingCalls(for: .inProgress) }
var accepted: Binding<[Call]> { bindingCalls(for: .accepted) }
var rejected: Binding<[Call]> { bindingCalls(for: .rejected) }
}
这是查看代码:
struct ContentView: View {
@StateObject var visitManager = CallManager(visits: [
Call(state: .inProgress),
Call(state: .accepted),
Call(state: .accepted),
Call(state: .inProgress),
Call(state: .inProgress),
Call(state: .rejected)
])
var body: some View {
HStack {
List(visitManager.inProgress) { $call in
CallView(call: $call)
}
List(visitManager.accepted) { $call in
CallView(call: $call)
}
List(visitManager.rejected) { $call in
CallView(call: $call)
}
}
}
}
struct CallView: View & Identifiable {
@Binding var call: Call
var id: UUID { call.id }
var body: some View {
Text(call.id.uuidString.prefix(15))
.foregroundColor(call.state.color)
.onTapGesture(count: 2) { call.state = .rejected }
.onTapGesture { call.state = .accepted }
}
}
extension Call.State {
var color: Color {
switch self {
case .inProgress: return .blue
case .rejected: return .red
case .accepted: return .green
}
}
}