首页 > 解决方案 > 无法在 WindowGroup SwiftUI Xcode 13.1 中为视图设置动画

问题描述

我现在有点难过,因为我一生都无法弄清楚为什么我的视图没有被动画化进出视图。

我目前正在使用 Xcode 13.1 和 SwiftUI 3.0。我目前正在尝试为从底部向上滑动的视图设置动画,当我们将 state 属性设置为 true 并且将此属性设置为 false 时,视图将向下滑动并从视图中移除。

没什么疯狂的,对我来说似乎很简单/直截了当,但是由于某种原因,当我更改 state 属性时,我根本没有得到动画,这很奇怪。

我觉得 WindowGroup 可能是问题所在,但我无法解释为什么这会影响动画。

下面是我目前正在使用的代码,它的效果不如显示我当前行为的 gif。


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 显示 SwiftUI 动画不起作用

标签: swiftswiftuiswiftui-animation

解决方案


删除 if 并使用 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
}

编辑 我真的不明白,这是你的目标吗?

在此处输入图像描述

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()
    }
}

推荐阅读