Como obter uma animação assim
Código: com este código eu consigo navegar pelas visualizações normalmente, mas se eu estiver dentro, AttendanceSwipeView(viewModel: viewModel)
se eu tocar no Dashboard, a visualização deverá vir com esse tipo de animação (como algo de baixo para frente) ...
quero dizer Painel> Atendimento> Feed ... a navegação pode ser normal, mas
do Feed ao Atendimento e do Atendimento ao Painel... aqui é necessário um tipo de animação completa. se possível, por favor me oriente como conseguir isso.
struct DashboardBottomView: View {
@StateObject var viewModel: AppDashboardViewModel
@State var selectedClassInd: Int = 0
@State private var stringArray = ["Dashboard", "Attendance", "Feed"]
@State private var selectedIndex: Int? = nil
@State private var selectedIndexStr: String? = "Dashboard"
private func viewForSelectedIndex() -> some View {
switch selectedIndexStr {
case "Dashboard":
return AnyView(DashboardView(viewModel: viewModel))
case "Attendance":
return AnyView(AttendanceSwipeView(viewModel: viewModel))
case "Feed":
return AnyView(DashboardFeedView())
default:
return AnyView(Text("Default View"))
}
}
var body: some View {
VStack(spacing: 0) {
Spacer()
ZStack {
viewForSelectedIndex()
.toolbar(.hidden, for: .navigationBar)
}
ZStack{
Color.appGreen2
ScrollView(.horizontal, showsIndicators: false) {
LazyHGrid(rows: [GridItem(.flexible(), spacing: 0)], spacing: 0) {
ForEach(stringArray, id: \.self) { data in
Button {
withAnimation {
selectedIndexStr = data
}
}
label: {
VStack {
Text(data)
.font(.calibriBold(with: 14))
.foregroundColor(Color.white)
.padding(.horizontal, 8)
if selectedIndexStr == data {
gradientDivider
.frame(height: 2)
}
}
.frame(height: 40)
.frame(minWidth: 108)
.animation(.default, value: selectedClassInd)
}
.buttonStyle(.plain)
}
}
.padding(.bottom, 0)
.background(Color.appGreen2)
}
.frame(height: 55)
}
}
.ignoresSafeArea()
.onAppear {
viewModel.fetchDashboardData { status in
if status {
stringArray = viewModel.dashboardButtonsArray
selectedIndexStr = stringArray.first
}
}
}
}
}
Uma transição personalizada pode ser usada aqui.
Uma transição personalizada pode ser aplicada
ViewModifier
à visualização em seu estadoactive
(antes) e (depois).identity
Quando a transição é animada, há interpolação automática entre os dois estados. Isto é adequado para uma transição linear simples, como parece ser o caso aqui.O seguinte
ViewModifier
aplica efeitos de opacidade, rotação e deslocamento à visualização:A transição personalizada pode ser definida como um
extension
paraAnyTransition
:Agora a transição personalizada está pronta para ser usada. O código abaixo é uma versão adaptada do seu exemplo, com as seguintes alterações:
Uma nova variável de estado
previousSelectedIndexStr
foi adicionada para registrar o alvo de navegação anterior.A ação do botão salva a seleção atual como
previousSelectedIndexStr
, antes de alterarselectedIndexStr
.A função
viewForSelectedIndex
foi marcada comoViewBuilder
. Isso evita ter que agrupar os diferentes tipos de resultados comoAnyView
.isSpecialTransitionNeeded
é uma propriedade computada que determina se a transição especial é necessária, com base no valor anterior e seguinte deselectedIndexStr
. Isso está fazendo uma comparação de strings como você estava usando antes, mas eu sugeriria que seria melhor usar um enum aqui.A parte superior
ZStack
inclui umaif
instrução que determina se uma transição diferente deve ser aplicada. Esta é uma maneira bastante primitiva, mas também fácil de alternar entre diferentes tipos de transição.A transição especial é usada apenas para a
insertion
transição, aremoval
transição é sempre.opacity
.Um
.animation
modificador foi adicionado ao arquivoZStack
. Isso controla a velocidade da transição. Para fins de demonstração,.gray
também foi aplicado como pano de fundo para o arquivoZStack
.O código que não foi compilado no seu exemplo original foi comentado ou substituído por alternativas simples.