如何在 Swift Xcode iOS 中以编程方式延迟启动屏幕

问题描述 投票:0回答:9

我在

image
中的
imageView
中放入了
LaunchStoreyboard
。如何以编程方式延迟图像时间?

这是 Apple 的 启动屏幕指南

这是启动屏幕视图控制器的代码

import UIKit
class LaunshViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.delay(0.4)
    }

    func delay(_ delay:Double, closure:@escaping ()->()) {
        let when = DispatchTime.now() + delay
        DispatchQueue.main.asyncAfter(deadline: when, execute: closure)
    }
}
ios swift xcode splash-screen timedelay
9个回答
83
投票

截至今天,Apple 还没有预定义方法来保持启动屏幕。这里有一些不是最佳但有效的方法

方法#1 创建一个单独的

ViewController
,它具有启动徽标并创建计时器或执行某些操作(例如数据库/加载一些基本的网络调用)取决于您的应用程序类型,这样您就可以提前准备好数据并按住启动屏幕: )

方法 #2 不是最佳

使用睡眠代码,让应用程序暂停一段时间。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        Thread.sleep(forTimeInterval: 3.0)
        // Override point for customization after application launch.
        return true
    }

24
投票

不建议将整个应用程序设置为等待状态。 如果应用程序在完成之前需要做更多工作,那么看门狗可能会因为启动时间过长而终止应用程序。

相反,您可以执行类似的操作来延迟启动屏幕。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        window = UIWindow(frame: UIScreen.main.bounds)
        window?.rootViewController = UIStoryboard(name: "LaunchScreen", bundle: nil).instantiateInitialViewController()
        window?.makeKeyAndVisible()

        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) {
            self.window?.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController()
        }
        return true
    }

24
投票

斯威夫特 4.x

让应用程序进入睡眠状态不是一个好习惯!

启动您的应用程序应该尽可能快,因此您不想使用启动屏幕延迟。

但是,您可以运行

loop,而不是 sleeping

,在此期间接收器处理来自所有附加输入源的数据:

这将延长启动屏幕的可见时间。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. RunLoop.current.run(until: NSDate(timeIntervalSinceNow:1) as Date) return true }
    

24
投票

Swift 5.x、iOS 13.x.x

修改

AppDelegate 类中的以下函数在 Swift 5.x/iOS 13.x.x 中不起作用。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. return true }

相反,您必须修改

SceneDelegate 类中的 scene 函数,如下所示。 它将延迟 LaunchSceen 3 秒。

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { window?.rootViewController = UIStoryboard(name: "LaunchScreen", bundle: nil).instantiateInitialViewController() window?.makeKeyAndVisible() DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) { self.window?.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController() } guard let _ = (scene as? UIWindowScene) else { return } }

window变量应该已经存在于SceneDelegate类中,如下所示。

var window: UIWindow?
    

3
投票
您的应用程序绝对不应该

进入睡眠状态,因为它可能会因长时间无响应而被操作系统杀死。 如果您在启动屏幕上使用静态图像,那么对我有用的是使用

LaunchScreen.storyboard

中的图像,然后当您的主控制器启动时,以模态方式呈现一个具有与背景相同的图像的 VC在主控制器的 ViewDidAppear 中(动画设置为 false)。 然后,您可以使用逻辑来了解何时关闭启动屏幕(VC 中的

dismiss

方法,动画设置为 false)。

实际

启动屏幕到我的 VC 呈现相同屏幕的过渡在我看来是难以察觉的。

PS

ViewDidAppear方法可能会被多次调用,在这种情况下,您需要使用逻辑来避免再次向VC显示启动屏幕。


2
投票

在ViewDidLoad方法中..

[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(fireMethod) userInfo:nil repeats:NO]; -(void)fireMethod { // push view controller here.. }



0
投票
SwiftUI

对于 SwiftUI,您可以将与接受的答案非常相似的代码放入 ContentView.onAppearing 中:

struct ContentView: View { var body: some View { Text("Hello") .onAppear { Thread.sleep(forTimeInterval: 3.0) } } }



0
投票

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Override point for customization after application launch. Thread.sleep(forTimeInterval: 3.0) return true }



-1
投票

我建议您转到 SceneDelegate 的“willConnectTo”函数并粘贴这段代码,然后就可以开始了。

window?.rootViewController = UIStoryboard(name: "LaunchScreen", bundle: nil).instantiateInitialViewController() window?.makeKeyAndVisible() DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) { self.window?.rootViewController = UIStoryboard(name: "Main", bundle: nil).instantiateInitialViewController() } guard let _ = (scene as? UIWindowScene) else { return }

© www.soinside.com 2019 - 2024. All rights reserved.