-1

I'm a bit stumped at the moment, since I can't for the life of me figure out why my view isn't being animated in and out of a view.

I'm currently using Xcode 13.1 & SwiftUI 3.0. I'm currently trying to animate a view sliding up from the bottom when we set a state property to true and when this property is set to false, the view will slide down and be removed from the view.

Nothing crazy it seems pretty simple/straightforward to me, but for some reason when I change the state property I don't get animation at all which is strange.

I feel like the WindowGroup may be the issue, but I can't put my finger on why this would be affecting the animation.

Below is the code that I'm currently using and isn't working as well as the gif showing the behavior I'm currently getting.


import SwiftUI

@main
struct MainApp: App {
    
    @State private var showCard = false
    
    var body: some Scene {
        WindowGroup {
                TabView {
                    Button("Show Card") {
                        withAnimation(.easeInOut(duration: 1)) {
                            showCard.toggle()
                        }
                    }
                    .tabItem {
                        Image.docViewFinder
                        Text("scan",
                             tableName: LocalisationTable.misc)
                    }
                    Text("Breakdowns")
                        .tabItem {
                            Image.stack
                            Text("breakdowns",
                                 tableName: LocalisationTable.misc)
                        }
                    Text("Home")
                        .tabItem {
                            Image.people
                            Text("people",
                                 tableName: LocalisationTable.misc)
                        }
                    Text("Home")
                        .tabItem {
                            Image.gear
                            Text("settings",
                                 tableName: LocalisationTable.misc)
                        }
                }
                .accentColor(.blue)
                .overlay(alignment: .bottom) {
                    if showCard {
                        Rectangle()
                            .edgesIgnoringSafeArea(.all)
                            .transition(.move(edge: .bottom))
                            .animation(.linear(duration: 1), value: showCard)
                            .frame(maxWidth: .infinity,
                                   maxHeight: 250)
                   }
                }
        }
    }
}

Gif showing the SwiftUI animation not working

Tunds
  • 1,804
  • 2
  • 15
  • 30
  • Have u tried to use ContentView instead? I am sure that would solve the issue. – ios coder Oct 26 '21 at 20:49
  • @swiftPunk Yep I've tried this also and it seems to be the same, I've also downloaded sample projects from other tutorials and it's the same. I have a feeling this may be a bug. – Tunds Oct 26 '21 at 20:53
  • I would never put direct code in `WindowGroup` there is the place that SwiftUI setup everything for us to get used! when you put code there the all the things are not there really for access to use! I am just saying due to my other experience! I strongly recommend use another view instead putting your code there! – ios coder Oct 26 '21 at 22:17

1 Answers1

-1

remove if and use offset

.overlay(alignment: .bottom) {

   Rectangle()
      .edgesIgnoringSafeArea(.all)
      .transition(.move(edge: .bottom))
      .animation(.linear(duration: 1), value: showCard)
      .frame(maxWidth: .infinity,
           maxHeight: 250)
      .offset(x: 0, y: showCard ? 250:0) //This
}

EDIT I really don't understand, is this your goal or not?

enter image description here

enum CardType: String {
    case clubs, diamonds, hearts, spades
    func imageName() -> String{
        switch self {
            case .clubs:
                return "suit.club"
            case .diamonds:
                return "diamond"
            case .hearts:
                return "heart"
            case .spades:
                return "suit.spade"
        }
    }
}

struct ShowView: View {
    
    @Binding var card: CardType
    @Binding var showCard: Bool
    
    private let allCards = [CardType.clubs, CardType.diamonds, CardType.hearts, CardType.spades]
    
    var body: some View {
        
        VStack {
            ZStack {
                Image(systemName: card.imageName())
                    .zIndex(3)
                    .foregroundColor(.blue)
               
            }
            Picker("card", selection: $card) {
                ForEach(allCards, id:\.self) { c in
                    Text("\(c.rawValue)")
                }
            }
            Image(systemName: "\(card.rawValue)")
            Button("Show Card \(showCard == true ? "on":"off")") {
                withAnimation(.easeInOut(duration: 1)) {
                    showCard.toggle()
                }
            }
        }
    }
}

@available(iOS 15.0, *)
struct ContentView: View {
    

    @State private var card: CardType = .clubs
    @State private var showCard = false
        
    var body: some View {
                      
        TabView {
            ShowView(card: $card, showCard: $showCard)
                .tabItem {
                    Text("scan")
                }
            Text("Breakdowns")
                .tabItem {
                    Text("breakdowns")
                }
            Text("Home")
                .tabItem {
                    Text("people")
                }
            Text("Home")
                .tabItem {
                    Text("settings")
                }
        }
        .accentColor(.blue)
        .overlay(alignment: .bottom) {
            Rectangle()
                 .edgesIgnoringSafeArea(.all)
                 .transition(.move(edge: .bottom))
                 .animation(.linear(duration: 0.5), value: showCard)
                 .frame(maxWidth: .infinity,
                      maxHeight: cardH(card))
                 .offset(x: 0, y: showCard ? 0:cardH(card))
                 .overlay() {
                     Image(systemName: card.imageName())
                         .zIndex(3)
                         .foregroundColor(.white)
                 }
        }
    }
    
    func cardH(_ type: CardType) -> CGFloat {
        switch type {
            case .clubs:
                return CGFloat(100)
            case .diamonds:
                return CGFloat(200)
            case .hearts:
                return CGFloat(300)
            case .spades:
                return CGFloat(400)
        }
    }
    
}

@available(iOS 15.0, *)
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
Simone Pistecchia
  • 2,746
  • 3
  • 18
  • 30