简体   繁体   English

我怎么能简单地将视图转换为 SwiftUI 视图?

[英]How could I simply have a View transition to SwiftUI View?

I'd like to implement a simple view transition through SwiftUI and Timer.我想通过 SwiftUI 和 Timer 实现一个简单的视图转换。 I have a primary View, it's content View.我有一个主视图,它是内容视图。 If I call func FireTimer() from in the View, the function fires timer.如果我从视图中调用 func FireTimer() ,该函数会触发计时器。 Then after 5 seconds, I would have a View transition.然后在 5 秒后,我会有一个视图转换。

I tried NavigationLink, but it has a button.我试过 NavigationLink,但它有一个按钮。 Timer can't push the button so now I'm confused.计时器无法按下按钮,所以现在我很困惑。 I'll show my code below.我将在下面展示我的代码。

TimerFire.swift TimerFire.swift

import Foundation
import UIKit
import SwiftUI

let TIME_MOVENEXT = 5
var timerCount : Int = 0

class TimerFire : ObservableObject{
    var workingTimer = Timer()

    @objc func FireTimer() {
        print("FireTimer")
        workingTimer = Timer.scheduledTimer(timeInterval: 1,     
            target: self,                                        
            selector: #selector(TimerFire.timerUpdate),      
            userInfo: nil,                                   
            repeats: true)                                   
    }

    @objc func timerUpdate(timeCount: Int) {
        timerCount += 1
        let timerText = "timerCount:\(timerCount)"
        print(timerText)

        if timerCount == TIME_MOVENEXT {
            print("timerCount == TIME_MOVENEXT")

            workingTimer.invalidate()
            print("workingTimer.invalidate()")
            timerCount = 0

            //
            //want to have a transition to SecondView here
            //
        }
    }
}

ContentView.swift内容视图.swift

import SwiftUI

struct ContentView: View {
    var body: some View {
        Button(action: {
            // What to perform
            let timerFire = TimerFire()
            timerFire.FireTimer()
        }) {
            // How the button looks like
            Text("Fire timer")
        }
    }
}

SecondView.swift SecondView.swift

import Foundation
import SwiftUI

struct SecondView: View {
    var body: some View {
        Text("Second World")
    }
}

How could I simply show this SecondView?我怎么能简单地显示这个 SecondView?

There is no code snippet for ContentView , so I tried to build simple example by myself. ContentView没有代码片段,所以我尝试自己构建简单的示例。 You can use NavigationLink(destination: _, isActive: Binding<Bool>, label: () -> _) in your case.您可以在您的情况下使用NavigationLink(destination: _, isActive: Binding<Bool>, label: () -> _) Change some State var while receiving changes from Timer.publish and you'll go to SecondView immediately:在从Timer.publish接收更改时更改一些State var,您将立即转到SecondView

struct TransitionWithTimer: View {

    @State var goToSecondWorld = false
    let timer = Timer.publish(every: 5, on: .main, in: .common).autoconnect()

    var body: some View {

        NavigationView {
            VStack {
                NavigationLink(destination: SecondWorld(), isActive: self.$goToSecondWorld) {
                    Text("First World")
                        .onReceive(timer) { _ in
                            self.goToSecondWorld = true
                    }
                }

            }

        }

    }
}

// you can use ZStack and opacity/offset of view's:

struct TransitionWithTimerAndOffset: View {

    @State var goToSecondWorld = false
    let timer = Timer.publish(every: 3, on: .main, in: .common).autoconnect()

    var body: some View {

        ZStack {
            Text("First world") // here can be your first View
                .opacity(self.goToSecondWorld ? 0 : 1)
                .offset(x: goToSecondWorld ? 1000 : 0)

            Text("Second world") // and here second world View
                .opacity(self.goToSecondWorld ? 1 : 0)
                .offset(x: goToSecondWorld ? 0 : -1000)
        }
        .onReceive(timer) { _ in
            withAnimation(.spring()) {
                self.goToSecondWorld = true
            }

        }

    }

}

struct SecondWorld: View {
    var body: some View {
        Text("Second World")
    }
}

Ok, if you want to do this w/o NavigationView on first screen (for any reason) here is a possible approach based on transition between two views.好的,如果您想在第一个屏幕上(出于任何原因)在没有NavigationView执行此操作,这是一种基于两个视图之间转换的可能方法。

Note: Preview has limited support for transitions, so please test on Simulator & real device注意:预览版对转场的支持有限,请在模拟器和真机上测试

Here is a demo how it looks (initial white screen is just Simulator launch)这是一个演示它的外观(初始白屏只是模拟器启动)

计时器上的 SwiftUI 转换

Here is single testing module:这是单个测试模块:

import SwiftUI
import UIKit

let TIME_MOVENEXT = 5
var timerCount : Int = 0

class TimerFire : ObservableObject{
    var workingTimer = Timer()
    @Published var completed = false

    @objc func FireTimer() {
        print("FireTimer")
        workingTimer = Timer.scheduledTimer(timeInterval: 1,
            target: self,
            selector: #selector(TimerFire.timerUpdate),
            userInfo: nil,
            repeats: true)
    }

    @objc func timerUpdate(timeCount: Int) {
        timerCount += 1
        let timerText = "timerCount:\(timerCount)"
        print(timerText)

        if timerCount == TIME_MOVENEXT {
            print("timerCount == TIME_MOVENEXT")

            workingTimer.invalidate()
            print("workingTimer.invalidate()")
            timerCount = 0

            //
            //want to have a transition to SecondView here
            //
            self.completed = true
        }
    }
}

struct SecondView: View {
    var body: some View {
        Text("Second World")
    }
}

struct TestTransitionByTimer: View {
    @ObservedObject var timer = TimerFire()

    @State var showDefault = true
    var body: some View {
        ZStack {
            Rectangle().fill(Color.clear) // << to make ZStack full-screen
            if showDefault {
                Rectangle().fill(Color.blue) // << just for demo
                    .overlay(Text("Hello, World!"))
                    .transition(.move(edge: .leading))
            }
            if !showDefault {
                Rectangle().fill(Color.red) // << just for demo
                    .overlay(SecondView())
                    .transition(.move(edge: .trailing))
            }
        }
        .onAppear {
            self.timer.FireTimer()
        }
        .onReceive(timer.$completed, perform: { completed in
            withAnimation {
                self.showDefault = !completed
            }
        })
    }
}

struct TestTransitionByTimer_Previews: PreviewProvider {
    static var previews: some View {
        TestTransitionByTimer()
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM