Using an Additional Screen in iOS

It's possible to add a second screen to an iOS device, either using an AirPlay with an Apple TV, or by using an AV adapter cable. The iOS simulator also lets us preview the output of the second screen, so testing is easy. This tutorial takes you through the process of adding a label to a second display.

  1. Start by creating a new single view iOS app in Xcode, using the Swift language, it does not matter what iOS device you create for.
  2. In order to ensure the steps below will work, carry out the following task, which prevents the application using Scenes (which is the default for iOS 13 projects)
    • Open the info.plist file and delete the entry named Application Scene Manifest (including its child entries)
    • Open the AppDelegate.swift file and remove (or comment out) the second and third methods (these appear under the line with the comment //MARK: UISceneSession Lifecycle)
    • Add the following as a property of the AppDelegate class:
      var window: UIWindow?
    • Optionally, you can also delete the SceneDelegate.swift file
  3. Apple's implementation of iOS has objects to represent Screens, Windows and Views. A UIWindow has a UIScreen property and it also has a UIView property, so we need to be responsible for creating both the Window and the View.

    Within the ViewController class declare two optional properties, a UIWindow and a UIView as follows:
    var secondWindow : UIWindow?
    var secondScreenView : UIView?
    The window and view are both optional because the user could remove the screen at anytime, or may not connect one at all.
  4. For the purposes of this tutorial, we are going to use a label to display text on the external screen, so add the following code to create a label for that purpose:
    var externalLabel = UILabel()
  5. Next we need to write code to handle the setup an attached screen. Add the following method (exposed to Objective-C) inside the ViewController to do just that:
    @objc func setupScreen(){
            
        if UIScreen.screens.count > 1{
        
            //find the second screen
            let secondScreen = UIScreen.screens[1]
        
            //set up a window for the screen using the screens pixel dimensions
            secondWindow = UIWindow(frame: secondScreen.bounds)
                                                                                                                                                                
            //windows require a root view controller
            let viewcontroller = UIViewController()
            secondWindow?.rootViewController = viewcontroller
    
            //tell the window which screen to use
            secondWindow?.screen = secondScreen
            
            //set the dimensions for the view for the external screen so it fills the screen
            secondScreenView = UIView(frame: secondWindow!.frame)
            
            //add the view to the second screens window
            secondWindow?.addSubview(secondScreenView!)
            
            //unhide the window
            secondWindow?.isHidden = false
            
            //customised the view
            secondScreenView!.backgroundColor = UIColor.white
            //configure the label
            externalLabel.textAlignment = NSTextAlignment.center
            externalLabel.font = UIFont(name: "Helvetica", size: 50.0)
            externalLabel.frame = secondScreenView!.bounds
            externalLabel.text = "Hello"
            
            //add the label to the view
            secondScreenView!.addSubview(externalLabel)
        }
    }
  6. As the user can connect and disconnect the screen at will, we need to register to be notified if that happens. Add the following code to do that
    func registerForScreenNotifications(){
        let notificationCentre = NotificationCenter.default   
        notificationCentre.addObserver(self, selector: #selector(ViewController.setupScreen), name: UIScreen.didConnectNotification, object: nil)
    }
  7. Finally, in the viewDidLoad method, add code to call the two methods you've just created:
    setupScreen()
    registerForScreenNotifications()
  8. Next run the application. Once the simulator is open, choose Hardware > External Displays and select one of the available dimensions (a smaller one would be better if your Mac has a small screen). You should see the word hello displayed in the centre of the simulated external display

An example project can be found on GitHub

Further Tasks