Getting a message I dont understand

I am attempting to use storyboard to switch scenes so my app doesnt just run when tapped/clicked.

The first scene is a controller scene which just shows an app intro and has two buttons one for start and other for cancel.

They both do the scene switch but neither activate the associated UIViewController.

I had not coded any action for the buttons just simply linked them to the associated subclassed UIViewControllers (eg Run and EndRun);

I added an NSLog entry in the viewDidLoad section in both of those and confirmed neither are activated.

The scene switching works fine going from intro to run and if that scenes stop button is tapped to the ended scene which is where the cancel button ends up.


I added an action in the initial UIViewController for the start button and an NSLog entry and linked the button to the action and that does show the button was tapped when it was.

I added the following, hoping it would do the segue:

[self performSegueWithIdentifier:@"RunSegue" sender:nil];


and got the message:

Attempt to present <UIViewController: 0x7be3f1e0> on <ViewController: 0xbfbfc50> whose view is not in the window hierarchy.


I am not sure if the UIViewController is refering to a class or instance of UIViewController and if the latter how do I got baout finding its name.

If its an instance I dont believe I have a permanent one with that name. (Not even sure you can as its a class name isnt it).

The initial UIViewController is called ViewController as that was what was generated when I created the project.

My app start UIViewController is called RunViewController and my app cancel or stop one is called EndRunViewController.


So where did the message get the UIViewController bit from and is the ViewController bit referring to my initial UIViewController?

Also if its the initial UIViewController how do I get it into the window hierarchy?


Anyone help?

Replies

I don't understand exactly your set up . So I'll ask a few questions. And create the app at the same time.


1. It's an IOS App ? XCode 9 ?


2. You have create 2 scenes with their UIViewControllers

- the first came with the creation of the storyboard.

-> I put a label on each View, respectively saying "First View" and "Second View"


3. Created 2 buttons in the first view

- one calle Run,

- the second Stop


4. You declared 2 subclasses of UIViewController,

I call them RunViewController and EndRunViewController

I do not create an associated xib file.


5. You define the class of the 2 viewControllers in IB as RunViewController and EndRunViewController


You say : I had not coded any action for the buttons just simply linked them to the associated subclassed UIViewControllers (eg Run and EndRun);

So how do you expect a click on the button will switch to the view ?


When I run the app:

- see the launch screen

- then see the firstView

- But of course, clicking on buttons does nothing. Normal.


6. So I added a link from Run:

- control-drag from the button to the second view (EndRunView)

- select show in the opoup


Now when I run, clicking on Run leads to the second view.


7. I understand you do it differently, by creating an IBAction on Run

I added an action in the initial UIViewController for the start button and an NSLog entry and linked the button to the action and that does show the button was tapped when it was.


8. The code of IBAction is

I added the following, hoping it would do the segue:

[self performSegueWithIdentifier:@"RunSegue" sender:nil];


If I run now and click Run, I get a crash, because segue is not defined.


9. How did you define the segue ?

You can do it in IB:

- control-drag from the left yellow button at the top of first view to the content of the second view, and select Manual / Show


If you run now, you transition to scond view when clicking Run.


Note : you may see that creating directly the segue from the button is simpler.


10. I added an NSLog in the IBAction. It shows on console.


11. I do not undertand what you did here :

stop button is tapped to the ended scene which is where the cancel button ends up.

1. It's an IOS App ? XCode 9 ?

No sorry should have stated. OSx is 10.10.5 Xcode is 6.4 target is iOS 5.1


2. You have create 2 scenes with their UIViewControllers

- the first came with the creation of the storyboard.

-> I put a label on each View, respectively saying "First View" and "Second View"

Yes Mine are labelled Run and EndRun. I ensured that the original scene was checked as the initial View Controller.

I tested at this point and the scenes showed as expected.


3. Created 2 buttons in the first view

- one calle Run,

- the second Stop

Yes except second is called Cancel as its on the first scene. Giving the user an option to change mind about running the app.

I did not connect them as I had not created the Action yet.


4. You declared 2 subclasses of UIViewController,

I call them RunViewController and EndRunViewController

I do not create an associated xib file.

Yes, I was expecing to have to need one for Run and EndRun scenes. The Run will run an animation.


5. You define the class of the 2 viewControllers in IB as RunViewController and EndRunViewController

You say : I had not coded any action for the buttons just simply linked them to the associated subclassed UIViewControllers (eg Run and EndRun);

So how do you expect a click on the button will switch to the view ?


At the time I had not understood about buttons and had to check some tutorials


When I run the app:

- see the launch screen

- then see the firstView

- But of course, clicking on buttons does nothing. Normal.

I added the action code for the start button into the original UIViewController (ViewController.m) so it just did a NSLog.


6. So I added a link from Run:

- control-drag from the button to the second view (EndRunView)

- select show in the opoup

Now when I run, clicking on Run leads to the second view.

Yes did the Ctrl-drag to connect the button to the action and the RunViewController scene showed and the NSLog from the Run/Start buttton showed.


7. I understand you do it differently, by creating an IBAction on Run

I added an action in the initial UIViewController for the start button and an NSLog entry and linked the button to the action and that does show the button was tapped when it was.

Yes thats it.


8. The code of IBAction is

I added the following, hoping it would do the segue:

[self performSegueWithIdentifier:@"RunSegue" sender:nil];

If I run now and click Run, I get a crash, because segue is not defined.

No I get the Attempt to present message.


9. How did you define the segue ?

You can do it in IB:

- control-drag from the left yellow button at the top of first view to the content of the second view, and select Manual / Show

If you run now, you transition to scond view when clicking Run.

Note : you may see that creating directly the segue from the button is simpler.


I did the Ctrl-drag and confirmed that the connections and segues all showed up in the Connections Inspector for each scene


10. I added an NSLog in the IBAction. It shows on console.

Yes


11. I do not undertand what you did here :

stop button is tapped to the ended scene which is where the cancel button ends up.


The Start/Run scene contains a button called Stop which at the moment does the scene switch but will, once I do the coding set a global variable StopRun to true also stop the animation.

The scene switch does occur but the animation does not. I added an NSLog into the RunViewControllers viewDidLoad and that does not show.

I am assuming the reason is to do with the message which I dont understand.


Do you know what the UIViewController and ViewController are referring to in the message?

Actions taken so far

1. Renamed ViewController files and class to InitialViewController to help in understnading whats going on.


2. Edited storyboard xml to add

customClass="EndRunViewController" to the EndRunViewController section

customClass="RunViewController" to the RunViewController section

and update

customClass="ViewController" to customClass="InitialViewController" in the original ViewControler secion thats now InitialViewController


When run this resulted in getting the NSLog output from the RunViewController scene when Start button was tapped.

But same Attempt warning message.


2. Added to InitialViewController.h (storyboard initial UIViewController) as suggested in another storyboard tutorial

#import "RunViewController.h"

#import "EndRunViewController.h"


When run this resulted in Debug messages

ViewContollerDidLoad

StartButtonTapped

RunViewControllerDidLoad

Warning: Attempt to present <RunViewController: 0x796d8c90> on <InitialViewControler: 0x79dea10> whose view is not in the window hierarchy!


Why isn't the view of the InitialViewController not in the window hierarchy?


Noticed: If I tapped the Stop button in the RunViewController scene I got EndRunViewControllerDidLoad log message so maybe I can simply ingnore the warning message now.

I do not see how you define the segue.


See my point 9 in previous post.

Sorry, I did realise I had not answered item 9. I did it as you described Ctrl-drag between the ViewController and the scene item which was confirmed together with the buttons in the Connections Inspector.

I have realised during my development that it is not a good idea to change the target device. I have got all sorts of starnge side effects.

This particular version of this app is destined to be delivered only to iPad 1 iOS 5.1 devices and as I have one of those will be continuing with only that device connected to my development macbook.

At this time I am back to being stuck with the old problem of getting a message about the storyboard file not being in the bundle.

If the runtime is expecting it to be in the app folder it will never find it as its always in the Base.lproj sub folder.

I have confirmed that there is a file there on the iPad.

I am now stuck with trawling through the many variations of solutions to this problem but so far not resolved it.

The build is working consistanly ok now but the Run is not.

For the moment I have commented out the actual functions for the app so I am only lookimng for the NSLog info.

I forget to mention an important point in 9.


9. How did you define the segue ?

You can do it in IB:

- control-drag from the left yellow button at the top of first view to the content of the second view, and select Manual / Show

- select the segue and give it the name RunSegue in Inspector

>So where did the message get the UIViewController bit from and is the ViewController bit referring to my initial UIViewController?


I'll assume Xcode 6.x isn't that different from this document (last updated a month ago), but have you seen 'Specailized Debugging Workflows/...using the Debug View Hierarchy button in the debug bar' etc. etc....?


https://developer.apple.com/library/content/documentation/DeveloperTools/Conceptual/debugging_with_xcode/chapters/special_debugging_workflows.html


>Renamed ViewController files and class to InitialViewController to help in understnading whats going on.


Using what process? Refactor/rename? Did you option-clean build folder after making those changes? Are you aware of the risks when name changing certain defaults and are you sure you avoided those issues?

Ctrl-drag to contents brings a popup title Manual Segue options are push, model and custom.

There is no show option. I chose modal and set the name in the inspector as RunSegue as you suggested.

That is what I had before.

Yes it is push.


does it work now ?

I continued with my efforts to remove all compiler message, including warnings.

The one I was left with was about internationalization for delivery for earlier than iOS 6.

The solution whoch I found in another forum entry was to change the Localization removing the Base just leaving English.

that removed the last warning message and now the app runs with the NSLog message appearing in the debug page.

Weird.

Onwards to getting the actual app code itself to run. I expect no problems as it did run ok before I introduced the storyboard.