Estou trabalhando em uma animação dentro do SwiftUI e enfrentei um problema ao usar a Visualização animada dentro de um TabView. Pesquisei muito e encontrei sempre a mesma abordagem para usar uma propriedade de estado com animações. Tudo funciona bem, exceto quando uso a visualização dentro de um TabView. Aqui está um código de exemplo
import SwiftUI
public struct AnimatedView: View {
@State var isRotating: Bool? = false
@State var isAnimating: Bool = true
public var body: some View {
ZStack {
Circle()
.trim(from:0.1, to: 0.2)
.stroke(lineWidth: 5)
.rotation(Angle.degrees(0))
.frame(width: 60, height: 60)
.foregroundColor(.blue)
.rotationEffect(.degrees(isRotating! ? 360 : 0))
.onAppear() {
//if !isAnimating {
// return
//}
//isAnimating = false
withAnimation(Animation.linear(duration: 1).repeatForever(autoreverses: false)) {
self.isRotating!.toggle()
}
}
}
}
}
struct ContentView: View {
enum Tab: Hashable {
case tab1
case tab2
}
@State private var selectedTab: Tab = .tab1
var body: some View {
TabView(selection: $selectedTab) {
Text("Placeholder 11")
.tabItem {
Text("Tab 1")
}
AnimatedView()
.tabItem {
Text("Tab 2")
}
}
}
}
Ao abrir a segunda aba tudo funciona bem, mas quando eu saio e entro novamente, a animação se comporta de forma diferente, pois parece que agora tem dois estados e fica ainda mais selvagem quando eu entro novamente na tela várias vezes. Cheguei à solução de que tenho outro sinalizador que será invertido após a primeira inicialização, para que a animação não seja reinicializada, mas isso me parece um pouco hackeado.
Pelo que entendi corretamente, os métodos onAppear e onDisappear serão chamados quando a View for fechada, mas seu estado será preservado. Portanto, parece que a mesma visão terá vários estados.
Como sou muito novo em animação, gostaria de saber se existe uma prática recomendada para animações, para que elas também funcionem dentro de TabViews (já que este não parece ser um caso especial para mim no momento :-)) Agradecemos antecipadamente
Levei um pouco de tentativa e erro para descobrir, mas no final consegui! Provavelmente é algum tipo de bug do SwiftUI. A solução foi simplesmente usar um valor de estado CGFloat diretamente no construtor de graus, assim:
Você faz com que comece de 0 e chegue a 360 com a animação linear, exatamente como estava fazendo. Deixe-me saber se isso funciona para você!