简体   繁体   中英

How to show a Text view after amount of seconds in SwiftUI?

I would like to show a Text saying "Keep the device vertical to continue" when the user keeps the device up for too long (around 3-4 seconds). What can I do? Any suggestions appreciated...

This is how the code looks like:

import SwiftUI
import CoreMotion

struct ContentView: View {

    let motionManager = CMMotionManager()
    let queue = OperationQueue()
    @State private var roll = Double.zero
    
    let timer = Timer.publish(every: 1, tolerance: 0.5, on: .main, in: .common).autoconnect()
    @State private var timeRemaining = 30

    var body: some View {
        VStack {
            Text("You have \(timeRemaining) seconds left")
                .onReceive(timer) { _ in
                    if timeRemaining > 0 {
                        timeRemaining -= 1
                    }
                }
            if roll < 1 {
            //Show "HIGH" if the user raises head
                Text("HIGH")
            } else if roll > 2.1 {
            //Show "LOW" if user lowers head
                Text("LOW")
            } else {
            //Otherwise show another Text view
                Text("Move the device!")
            }
        }
        .onAppear {
            //Detect device motion
            self.motionManager.startDeviceMotionUpdates(to: self.queue) { (data: CMDeviceMotion?, error: Error?) in
                guard let data = data else {
                    print("Error: \(error!)")
                    return
                }
                let attitude: CMAttitude = data.attitude
                
                DispatchQueue.main.async {
                    self.roll = attitude.roll
                }
            }
        }
    }
}

Option 1 (less changes)

DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
    //Do your work, will run after 3 seconds               
}

Option 2 (my preference)

Concept

  • Use Task.sleep(nanoseconds:) - This is an async function which will suspend for n nanoseconds. It will not block the main thread
  • Use it inside task { } which gets called when view appears and is used to do any async work
  • Would be nice to learn about Swift Concurrency and how it can be used with SwiftUI

Sample Code

struct ContentView: View {
    @State private var roll = Double.zero
    
    var body: some View {
        VStack {
            Text("Hello World!")
            
            if roll < 1 {
                //Show "HIGH" if the user raises head
                Text("HIGH")
            } else if roll > 2.1 {
                //Show "LOW" if user lowers head
                Text("LOW")
            } else {
                //Otherwise show another Text view
                Text("Move the device!")
            }
        }
        .task {
            //Suspends for 3 seconds
            try? await Task.sleep(nanoseconds: 3_000_000_000)
            roll = 3
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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