One, foreword

As we know, In WWDC 2019, Apple mandated the use of launchscreen. storyboard for all apps starting in April 2020. The era of removing this storyboard and replacing it with various customized AD launch pages has passed. There are various promotions (more and more frequent, and promotions on holidays) every year, so the event pages are still essential. The launch page cannot be deleted, and we also need the advertising page, so how do we do that?

Here’s what you’ll learn:

  1. LaunchScreen;
  2. Make startup page + XIB setting constraints;
  3. Double UIWindow/single UIWindow toggle;

A brief introduction to LaunchScreen

LaunchScreen is simple, and there are plenty of online adaptations. You can’t set the storyboard dynamically, you can only set it in advance in Xcode. It is not recommended to use a whole image + constraint because of the compatibility between different resolutions, unless you add a whole set of images with different resolutions to the project, in which case your entire app package will be too large.

Personal advice:

  • The background is solid color filling;
  • Place small graph + constraint;
  • Place text + constraint;

For the sake of the Demo, I set up a whole image + two lines of text:

  • The image uses “Aspect Fill” to Fill the whole screen proportionally (it will be captured), so why do I suggest using a pure background color? Of course, if you are not afraid of being captured, you can use the image without any problem;
  • Different color text Settings, as shown below:

How do I add constraints to a XIB?

When dragging the line, hold down the “Control” key first!

UIWindow and AD page

In the AppDelegate, we already have a window, and its rootViewController is set to our MainTabBarController, so how do we start our AD page first, And then go to our real TabBarController?

In general, we have two approaches:

  1. Single window, rootViewController first sets AD page VC and then TabBarController;
  2. Double Window, rootViewController sets the AD page VC and TabBarController respectively, except that the AD page Window is at the top and then switches to the TabBarController window;

Either way, the end result is the same, as shown below:

3.1. Add AD page VC

// AdvertiseViewController.swift

class AdvertiseViewController: BaseViewController {
    
    // Delay the timer initialization
    lazy var timer = DispatchSource.makeTimerSource(flags: [], queue: DispatchQueue.global())
    // Count down the time
    var seconds = 5

    override func viewDidLoad(a) {
        super.viewDidLoad()
        view.backgroundColor = .kRed
        timeCountDown()
    }
    
    func timeCountDown(a) {
        timer.schedule(deadline: .now(), repeating: .seconds(1))
        timer.setEventHandler(handler: {
            DispatchQueue.main.async { [weak self] in
                
                // When the timer is smaller than or equal to 0, end the timer and switch the two RootViewControllers
                if self!.seconds < = 0 {
                    self!.terminer()
                }
                self!.seconds - = 1
            }
        })
        timer.resume()
    }
    
    func terminer(a) {
        timer.cancel()
    }
}
Copy the code

3.2. Single-window replacement method

Single window replacement method, as I said before, the user clicks or at the end of the countdown, the window. The rootViewController = MainTabBarController () can, of course, also add some transition animations, too stiff, or it will show the implementation code is as follows:

// AdvertiseViewController.swift

class AdvertiseViewController: BaseViewController {
    .
    
    func terminer(a) {
        timer.cancel()
        switchRootController()
    }
    
    //
    // A window case: just toggle rootViewController
    //
    func switchRootController(a) {
        let window = UIApplication.shared.windows.first!
        
        // Transition animation: 0.5s fades out
        UIView.transition(with: window,
                          duration: 0.5,
                          options: .transitionCrossDissolve,
                          animations: {
                            
                            let old = UIView.areAnimationsEnabled
                            UIView.setAnimationsEnabled(false)
                            window.rootViewController = MainTabBarController(a)UIView.setAnimationsEnabled(old)

                          }, completion: { _ in
                            // Do Nothing}}})Copy the code

Modify AppDelegation

@main
class AppDelegate: UIResponder.UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication.didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        
        window = UIWindow(frame: UIScreen.main.bounds)
        window?.backgroundColor = .white
        window?.rootViewController = AdvertiseViewController(a)// Modify this
        window?.makeKeyAndVisible()
        
        return true}}Copy the code

3.3. Double Window switching method

A double Window, as the name suggests, has two Windows. Unlike a single window, a double Window changes the rootViewController. Instead, it switches through the API to control which window is visible. (Restore the code to section 3.1 before starting the demo in this section)

Modify AppDelegation

@main
class AppDelegate: UIResponder.UIApplicationDelegate {

    // multiple Windows:
    // The first one is for the main app;
    // Display AD page;
    var windows: [UIWindow]?

    func application(_ application: UIApplication.didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        
        // The last window is placed on top of the previous one.
        // windows? [subscript].makeKeyAndVisible() to switch the display
        windows = [
            addWindowWithVC(MainTabBarController()),
            addWindowWithVC(AdvertiseViewController())"return true
    }

    func addWindowWithVC(_ vc: UIViewController) -> UIWindow {
        let window = UIWindow.init(frame: UIScreen.main.bounds)
        window.backgroundColor = .white
        window.rootViewController = vc
        window.makeKeyAndVisible()
        return window
    }
}
Copy the code

Modify AdvertiseViewController

class AdvertiseViewController: BaseViewController {
    .
    
    func terminer(a) {
        timer.cancel()
        switchWindow() // Modify this
    }
    
    // The same two ways can be achieved: advertising page -> home page:
    // 1. Use two Windows to control different services, and then switch Windows based on transition animation;
    / / 2. A window, two vc, is the main vc and advertising vc respectively, by changing the window. The rootViewController to complete;
    func switchWindow(a) {
        // open the second window.
        let window = UIApplication.shared.windows.last!
        
        // Transition animation: fade out
        UIView.transition(with: window,
                          duration: 0.5,
                          options: .transitionCrossDissolve,
                          animations: {

                            // Temporarily save the state of whether the UIView is enabled for animation (default is enabled)
                            // It is forbidden first to prevent other animations from affecting the current animation
                            // ----------------------------------------
                            // Disable animation:
                            // 1. All currently executing animations have no effect
                            // 2. Unexecuted animations will not be executed
                            // ----------------------------------------
                            //
                            // Since our callback is already animated, it is not forced to stop,
                            // Finally restore UIView to enable animation state
                            let old = UIView.areAnimationsEnabled
                            UIView.setAnimationsEnabled(false)
                            window.alpha = 0
                            UIView.setAnimationsEnabled(old)

                          }, completion: { _ in
                            // Switch to the main window, our MainTabBarController
                            UIApplication.shared.windows.first?.makeKeyAndVisible()
                          })
    }
Copy the code

Either way, it’s the same to the user; Again, the final decision on whether to use single-window or dual-window depends on the project (scalability), r&d (technology, time, capability), etc. But at the end of the day, one more solution, one more path.

Four,

This article will show you how to use multiple Windows, and how to animate the transition between them. It seems that there are not many scenes with multiple Windows, but in fact there are some. For example, in video APP, when the page is not in full screen, and the video control moves out of the screen and becomes invisible, the APP will create a separate video window suspended in the lower right corner, which uses the multi-window technology.

Since it is an advertising page, there must be a countdown control constantly decreasing time, after the end of the countdown will enter our home page. In the next article, I’ll introduce the first component of this series: the countdown component! (This series will cover custom development of many common components.)

Welcome to exchange, please look forward to, thank you!