Simulator is blank

Hi,


The simulator is blank and Xcode displays class AppDelegate. I have done Clean, redoing the outlets and restarting Xcode, none of which have worked. What can I do now?


Thanks in advance

Replies

There is no 'Clean' with current Xcode.


What version Xcode are you using?


What happens if you build a sample project using Xcode's single window template and run that in the simulator?

Have you defined a viewController as the initial screen ?

Hi,


Thanks guys for responding.


I am using Xcode version 9.4.1.


I have tried running other apps that I built and they work fine on the simulator.


When I run this project on the simulator, it automatically pops up the Apple Delegate file and there is a line with a message that reads, “Thread 1: Signal SIGABRT”.


In this project I am trying to learn the protocols and delegates method and I am following Sean Allen’s YouTube lesson.


I am have a ‘Base Screen’:


import UIKit


class BaseScreen: UIViewController {

@IBOutlet weak var mainImageView: UIImageView!

@IBOutlet weak var chooseButton: UIButton!

@IBOutlet weak var nameLabel: UILabel!


override func viewDidLoad() {

super.viewDidLoad()

chooseButton.layer.cornerRadius = chooseButton.frame.size.height/2

}


@IBAction func chooseButton(_ sender: UIButton) {

//Create selection view controller

let selectionVC = storyboard?.instantiateViewController(withIdentifier: "SelectionScreen") as! SelectionScreen

selectionVC.selectionDelegate = self

//Presenting the VC

present(selectionVC, animated: true, completion: nil)

}

}

//Create delegate function

extension BaseScreen: SideSelectionDelegate {

func didTapChoice(image: UIImage, name: String, color: UIColor) {

mainImageView.image = image

nameLabel.text = name

view.backgroundColor = color

}

}


And a ‘Selection Screen’:


import UIKit


//Establish protocol function (list of commands)

protocol SideSelectionDelegate {

func didTapChoice(image: UIImage, name: String, color: UIColor)

}


class SelectionScreen: UIViewController {

//Create variable to hold delegate

var selectionDelegate: SideSelectionDelegate!


override func viewDidLoad() {

super.viewDidLoad()

}

//Create commands for delegate to call:

@IBAction func imperialButtonTapped(_ sender: UIButton) {

selectionDelegate.didTapChoice(image: UIImage(named: "vader")!, name: "Darth Vader", color: .red)

dismiss(animated: true, completion: nil)

}

//Create commands for delegate to call:

@IBAction func rebelButtonTapped(_ sender: UIButton) {

selectionDelegate.didTapChoice(image: UIImage(named: "luke")!, name: "Luke Skywalker", color: .cyan)

dismiss(animated: true, completion: nil)

}

}


Have I defined a View Controller as the initial screen? I don’t know to be honest. How do I do that?


Thanks in advance again…

Have I defined a View Controller as the initial screen?


In Interface Builder (IB), look at the storyboard. Is there an arrow coming from no other view, pointing to one view ? If yes, this is the initial view.

You can check by selecting the view controller ; in the Attributes inspector, the Is initial view checkbox must be ON.


Check the same for the launchScreen.


But your problem must be elsewhere, as you have a crash.


You should check the connections of IBOutlets

@IBOutlet weak var mainImageView: UIImageView!

@IBOutlet weak var chooseButton: UIButton!

@IBOutlet weak var nameLabel: UILabel!


Do you see the dot on the left as black ?

If no, connect to the object in IB


If yes, may be connections are corrupted.


Remove all the connections : in IB, select the object associated to each IBOutlet and open Connextions Inspector.

Uncheck the small check box at the left of connection.

The black dot should become white


Recreate the right connection.



At the end, do a Clean Build Folder (menu Product, press option key and select the option).

Hi Calude31,


Yes the Base Screen is the initail screen. I can't fix this. I tried reconnecting the IB outlets. I don't know what I've done wrong. I just don't understand enough to troubleshoot this for now. I will continue working on other Xcode projects and revisit this problem down the track and hopefully by then I know more to fix this.


Thank you for your help

In such a case, when you don't find the problem, a good way is to eliminate (commenting out) some parts and see if it works


import UIKit


class BaseScreen: UIViewController { 
  
    @IBOutlet weak var mainImageView: UIImageView!
    @IBOutlet weak var chooseButton: UIButton!
    @IBOutlet weak var nameLabel: UILabel!
 
    override func viewDidLoad() {
        super.viewDidLoad()
        chooseButton.layer.cornerRadius = chooseButton.frame.size.height/2
        }
 
    @IBAction func chooseButton(_ sender: UIButton) {
  
        //Create selection view controller
        let selectionVC = storyboard?.instantiateViewController(withIdentifier: "SelectionScreen") as! SelectionScreen
        selectionVC.selectionDelegate = self
        //Presenting the VC
        present(selectionVC, animated: true, completion: nil)
  
    }
}
//Create delegate function
extension BaseScreen: SideSelectionDelegate {
  
    func didTapChoice(image: UIImage, name: String, color: UIColor) {
        mainImageView.image = image
        nameLabel.text = name
        view.backgroundColor = color
    }
  
}



Here, comment out line 09.


If does not work, comment out lines 23 to 31.

Hi Claude31,


So I started the project from scratch and made some headway but not 100% home yet. I manage to get the first initial screen ('Base Screen') on the simulator but when I click on the 'Choose a Side' button, it does not bring up the second View Controller ('Selection Screen').


There is an "Unsupported Configuration' yellow triangle warning that says: "Selection Screen is unreachable because it has no entry points, and no identifier for runtime access via - [UIStoryboard instantiateViewController WithIdentifier:]."


I created the Base Screen as a swift file and the Selection Screen as Cocoa Touch Class file - because when I created it as a swift file the first time it wouldn't let me create IB outlets. All the outlets are sound (cirles with black dots). I tried connecting segues from 'Choose a Side' button to the Selection Screen but that didn't help.


Is the issue maybe some where in line 22-23 of the Base Screen (

"let selectionVC = storyboard?.instantiateViewController(withIdentifier: "SelectionScreen") as! SelectionScreen

selectionVC.SelectionDelegate = self")?


Any idea how to fix this?


Here are the codes again:


1.

BaseScreen.swift


import UIKit


class BaseScreen: UIViewController {


@IBOutlet weak var mainImageView: UIImageView!

@IBOutlet weak var chooseButton: UIButton!

@IBOutlet weak var nameLabel: UILabel!


override func viewDidLoad() {

super.viewDidLoad()

}


@IBAction func chooseButtonTapped(_ sender: UIButton) {

let selectionVC = storyboard?.instantiateViewController(withIdentifier: "SelectionScreen") as! SelectionScreen

selectionVC.SelectionDelegate = self

present(selectionVC, animated: true, completion: nil)

}

}


extension BaseScreen: SideSelectionDelegate {

func didTapChoice(image: UIImage, name: String, color: UIColor) {

mainImageView.image = image

nameLabel.text = name

view.backgroundColor = color

}


}



2.

SelectionScreen.swift


import UIKit


protocol SideSelectionDelegate {

func didTapChoice(image: UIImage, name: String, color: UIColor)


}


class SelectionScreen: UIViewController {


var SelectionDelegate: SideSelectionDelegate!


override func viewDidLoad() {

super.viewDidLoad()


}


@IBAction func imperialButtonTapped(_ sender: UIButton) {

SelectionDelegate.didTapChoice(image: UIImage(named: "vader")!, name: "Darth Vader", color: .red)

dismiss(animated: true, completion: nil)

}


@IBAction func rebelButtonTapped(_ sender: UIButton) {

SelectionDelegate.didTapChoice(image: UIImage(named: "luke")!, name: "Luke Skywalker", color: .cyan)

dismiss(animated: true, completion: nil)

}

}


Cheers and thanks again

The simplest is to create the segue from the button to the ViewController.


In IB (Interface Builder):

- control-drag from the "chooseButton" button to the ViewController where you want to go

- Select show in the popup that appears.


In BaseScreen, remove the IBAction (just comment it out):

    @IBAction func chooseButtonTapped(_ sender: UIButton) {
        let selectionVC = storyboard?.instantiateViewController(withIdentifier: "SelectionScreen") as! SelectionScreen
        selectionVC.SelectionDelegate = self
        present(selectionVC, animated: true, completion: nil)
    }
}


Now, the button should work.


You will need also a prepare for segue if you want to pass data to the destination controller.


To explain your problem with present code:

- Have you checked the identifier of destination view is SelectionScreen, with the right uppercase ? Normally, if it was not, the app should crash because of the as!

- To check you get there, add a print statement:

    @IBAction func chooseButtonTapped(_ sender: UIButton) {
        let selectionVC = storyboard?.instantiateViewController(withIdentifier: "SelectionScreen") as! SelectionScreen
        selectionVC.SelectionDelegate = self
        print("chooseButtonTapped", selectionVC)
        present(selectionVC, animated: true, completion: nil)
    }


- Have you defined a segue to go to SelectionScreen ? I understand yes. Does it have an Identifier ?

- Do a Clean Build Folder (option clean in Product Menu)


- Note: a property should start with lowerCase:

selectionDelegate and not SelectionDelegate