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
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
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