Сломанная анимация SwiftUI при использовании TabView
У меня есть рабочая анимация в представлении SwiftUI, которая прерывается, когда я помещаю это представление в, перехожу на другую вкладку и возвращаюсь. Как я могу это исправить?
Моя точка зрения более сложна, но я свел ее к следующему:
import SwiftUI
@main
struct AnimationTestApp: App {
var body: some Scene {
WindowGroup {
TabView {
ContentView()
.tabItem {
Text("Tab 1")
}
Text("Content 2")
.tabItem {
Text("Tab 2")
}
}
}
}
}
struct ContentView: View {
@StateObject private var viewModel = ViewModel()
@Namespace var namespace
var body: some View {
VStack {
Button(action: {
viewModel.move()
}) {
Text("Move")
}
ZStack() {
Rectangle()
.fill(.gray)
.frame(width: 300, height: 300, alignment: .center)
if viewModel.moved {
RectView()
.matchedGeometryEffect(id: 0, in: namespace, properties: .frame)
.animation(Animation.default.speed(0.5))
.offset(x: 0, y: -130)
} else {
RectView()
.matchedGeometryEffect(id: 0, in: namespace, properties: .frame)
.animation(Animation.default.speed(0.5))
.offset(x: 0, y: 130)
}
}
}
}
}
struct RectView: View {
var body: some View {
Rectangle()
.frame(width: 100, height: 30, alignment: .center)
}
}
final class ViewModel: ObservableObject {
@Published var moved = false
func move() {
moved = !moved
}
}
Вот запись этого кода на экране. При нажатии анимация плавно перемещается вверх и вниз. После перехода на
Tab 2
и возвращаясь, когда я в первый раз нажимаю
Move
, он прыгает без анимации. Следующие нажатия снова анимируются.
На самом деле модель представления более сложная. Состояние (в данном случае:
moved
) изменяется через некоторое время после нажатия кнопки. Некоторая работа выполняется в фоновом потоке, а затем изменение состояния запускается в основном потоке. Вот почему я не могу переместить анимацию в
Button
действие.
Также вид более сложный. В
RectView
удаляется из глубины иерархии представлений и добавляется где-то совсем в другом месте.
Метод
func animation(_ animation: Animation?)
устарела в iOS 15. Проблема уже существует в iOS 14 навсегда. Я также попытался удалить
animation
модификаторы и поставьте
moved = !moved
в
withAnimation { }
блокировать. Все тот же результат.
Как я мог это исправить, сохранив
TabView
?
1 ответ
У вас была некоторая проблема с кодированием, вот рабочий код, также вам не нужен
import SwiftUI
@main
struct AnimationTestApp: App {
var body: some Scene {
WindowGroup {
TabView {
ContentView()
.tabItem {
Text("Tab 1")
}
Text("Content 2")
.tabItem {
Text("Tab 2")
}
}
}
}
}
struct ContentView: View {
@StateObject private var viewModel = ViewModel()
var body: some View {
VStack {
Button(action: { viewModel.moved.toggle() }) {
Text("Move")
}
ZStack() {
Rectangle()
.fill(Color.gray)
.frame(width: 300, height: 300, alignment: .center)
RectView()
.offset(x: 0, y: viewModel.moved ? -130 : 130)
.animation(Animation.default.speed(0.5), value: viewModel.moved)
}
}
}
}
struct RectView: View {
var body: some View {
Rectangle()
.frame(width: 100, height: 30)
}
}
final class ViewModel: ObservableObject {
@Published var moved: Bool = false
}