Search code examples
swift3xcode8ios10splash-screendynamic-splash-screen

How to load array of images with custom delay into splash screen Swift 3 Xcode 8?


I want to load an array of images before the app show its views to user, with a custom delay for example 5 milliseconds . any help ??

I've used UIImageView in UIViewController and this is my code:

import UIKit

class CustomViewController: UIViewController {


@IBOutlet weak var imageView: UIImageView!

var logoImage: [UIImage] = [
    UIImage(named: "splash_logo_1.png")!,
    UIImage(named: "splash_logo_2.png")!,
    UIImage(named: "splash_logo_3.png")!,
    UIImage(named: "splash_logo_4.png")!,
    UIImage(named: "splash_logo_5.png")!,
    UIImage(named: "splash_logo_6.png")!,
    UIImage(named: "splash_logo_7.png")!,
    UIImage(named: "splash_logo_8.png")!,
    UIImage(named: "splash_logo_9.png")!,

]

override func viewDidLoad() {
    super.viewDidLoad()

    // Do any additional setup after loading the view.
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.8 , execute: {
        // Put your code which should be executed with a delay here
        for i in 1..<self.logoImage.count
        {
            let image = self.logoImage[i]
            self.imageView.image = image
        }
    })

}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

after building the app, it only shows the last image (plash_logo_9.png).

so where is the problem ..?


Solution

  • You are starting to display the images too soon for the user. viewDidLoad only means, that your viewController has been loaded to the memory, and ready for initial setup, however, it is not visible for the user.

    In order to make the presentation visible to the user, i would recommend to start displaying it in viewDidAppear, and only set the first image in viewDidLoad.

    At the end, you should change the for and dispatch calls order. You need to create as many dispatch blocks, with a delay constantly increased, as many images you have.

    So, remove viewDidLoad and replace it with this:

     override func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(animated)
    
            var delay: Double = 0 
            for i in 0..<self.logoImage.count {
                DispatchQueue.main.asyncAfter(deadline: .now() + delay, execute: {
                    // Put your code which should be executed with a delay here
                    let image = self.logoImage[i]
                    self.imageView.image = image
                })
                delay += 0.8
            }
        }
    

    Furthermore, i would recommend to read more about the viewControllers lifecycle.