在SwiftUI中,如何为发布视图更改设置动画?

时间:2020-05-09 11:15:59

标签: swift swiftui

我想为视图更改设置动画。
特别是,我完成了一个视图,其中一个子视图是一个不断变化的视图。

struct MasterView: View {

    @State var playerLeft: Bool = false
    @ObservedObject var viewModel: MasterViewModel

    var body: some View {
        ZStack {
            WaitPlayerBackView(isShowing: self.$playerLeft) {
                self.viewModel.currentView
            }
        }
    }
}

视图模型是一个ObservableObject类。 currentView可以通过异步线程中调用的方法来更改,如下所示:

class MasterViewModel: ObservableObject {
    @Published var currentView: AnyView = AnyView(EmptyView())

    func changeView() {
        self.currentView = AnyView(NightView())
    }
}

这就像是Android片段的副本(请比较)。
如何为该视图更改设置动画?
我尝试了其他选项,例如:

self.viewModel.currentView.animate(.default)

struct MasterView: View {

    @State var playerLeft: Bool = false
    @ObservedObject var viewModel: MasterViewModel

    var body: some View {
        ZStack {
            WaitPlayerBackView(isShowing: self.$playerLeft) {
                self.viewModel.currentView
            }
        }.animate(self.viewModel.animate ? .easeIn(duration: 1) : .none)
    }
}

class MasterViewModel: ObservableObject {
    @Published var currentView: AnyView = AnyView(EmptyView())
    @Published var animate = false

    func changeView() {
        self.animate = false
        self.currentView = AnyView(NightView())
        self.animate = true
    }
}

但是,它们都不起作用。
这是我在更改currentView实例时看到的过渡。 Example of transitions

1 个答案:

答案 0 :(得分:1)

将视图初始化移至MasterView可使一切变得更容易:

struct MasterView: View {

    @State var playerLeft: Bool = false
    @ObservedObject var viewModel: MasterViewModel

    var body: some View {
        ZStack {
            VStack { //this represents WaitPlayerBackView
                if viewModel.day { //here are the posibles views that self.viewModel.currentView could have
                    Text("DayView").transition(AnyTransition.opacity.animation(.easeInOut(duration: 1.0)))
                } else {
                    Text("NightView").transition(AnyTransition.opacity.animation(.(duration: 1.0)))
                }
            }
        }
    }
}

class MasterViewModel: ObservableObject {
    @Published var day: Bool = false

    init () {
        _ = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(changeView), userInfo: nil, repeats: true) //Only for testing
    }
    @objc func changeView() { //@objc is only for testing
        day.toggle()
    }
}