Я кодирую свое приложение в SwiftUI и пытаюсь следовать их декларативным соглашениям, но я немного отклеился.
У меня есть модель данных, которая передается через иерархию представлений с помощью привязок, и одно из моих дочерних представлений имеет возможность изменить несколько свойств в модели, чтобы вызвать изменение макета.
Поскольку его анимация является функцией данных, мне нужно пошатнуть изменение модели, чтобы получить нужную анимацию. Вот простой пример;Предположим, мне нужно очистить содержимое дочернего представления по архитектурным причинам. Каков наилучший способ сделать так, чтобы содержимое перетаскивалось на красную панель перед анимацией ChildView, а затем, когда оно закрыто, дождитесь окончания анимации, прежде чем удалять содержимое?
struct ContentView: View {
@State var contents: [String] = ["A", "B", "C", "A", "B", "C", "A", "B", "C"]
@State var showingPanel: Bool = false
var body: some View {
VStack {
HStack {
Button(action: {
self.contents = ["A", "B", "C", "A", "B", "C", "A", "B", "C"]
self.showingPanel = true
}) {
Text("Show Panel")
}
Button(action: {
self.showingPanel = false
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
self.contents = []
}
}) {
Text("Clear Panel")
}
}
ChildView(showingPanel: $showingPanel, contents: $contents)
}
}
}
struct ChildView: View {
@Binding var showingPanel: Bool
@Binding var contents: [String]
var body: some View {
ZStack {
Color.red
VStack {
ForEach(contents, id: \.self) { content in
Text(content).font(.title)
}
}.animation(nil)
}.offset(y: showingPanel ? 0 : UIScreen.main.bounds.size.height).animation(.default)
}
}
Моим первым ударом былоиспользуйте DispatchQueue, чтобы попытаться отложить изменение, но это выглядит неправильно и тоже не работает!