Scene is unreachable due to lack of entry points... Custom Button - objective-c

I'm new to programming on xCode. I've made a login screen in a snapchat format. Currently, I started with two view controllers one for login and then signup but I changed it so I start with an intial view controller that has two custom buttons I made. View the picture. I want it to be that so when you clean the login button it takes you to the login screen and when you click the sign up button it takes you to the sign up screen.
I'm not sure what I'm doing wrong. I want![enter image description here][1]
My app delegate has the following:
http://i.stack.imgur.com/8fWT4.png
http://i.stack.imgur.com/b9mfN.png
I just don't understand as to why I keep getting the following error: Scene is unreachable due to lack of entry points and does not have an identifier for runtime access via -instantiateViewControllerWithIdentifier:.

Unless your segueing to the view in question, you would need to give it a storyboard identifier to connect the nib with the related class. Go into the storyboard and ensure you've set the class and storyboard id. If you're segueing to the class, ensure you give your segue an identifier. But if not, you can then do something like:
YourViewController *vc = (YourViewController*)[self.storyboard instantiateViewControllerWithIndentifier:#"YourStoryboardIdentifier"];
[self presentViewController:vc animated:YES completion:^{}];// Or however you want to present it. ie pushing onto the navigation stack

You can use this code:
WaitingRoomVC *ivc=[self.storyboard instantiateViewControllerWithIdentifier:#"waiting"];
[self.navigationController pushViewController:ivc animated:YES];

Related

How to switch views using UIStoryboard and UIViewcontroller

I'm still pretty new to Obj-C and iOS so bear with me. In my app I am trying to implement a share button that brings up a second view in the current view controller. I'm following this tutorial(http://www.youtube.com/watch?v=DZ3SyGInklQ) and I run into a problem where the dev uses initWithNibName and I am using a storyboard. I'm wondering why my second view is not coming up when I press my button. It's probably very obvious but I can't figure it out.
Heres some of my current code:
Menu.h
//Share button
- (IBAction)shareButton:(id)sender;
Menu.M
- (IBAction)shareButton:(id)sender {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MenuStoryboard" bundle:nil];
UIViewController *sharebuttonview = (UIViewController *)[storyboard instantiateViewControllerWithIdentifier:#"sharebuttonview"];
[self presentViewController:sharebuttonview animated:YES completion:NULL];
}
First you go into the storyboard and then you connect the Share Button with the View you want to show. After that you name this segue with an Identifier.
In you Menu.M in the IBAction you write:
[self performSegueWithIdentifier:#"mySegueIdentifier" sender:self];
(mySegueIdentifier is the Identifier you used before)
Based on your description of the issue it appears that you may want to do a manual segue, which allows you to open a target view controller from any number of UI controls. The workflow has changed from Xcode 5 compared to prior versions of Xcode. You may want to see my blog post for additional tips but essentially you will want to open your storyboard and do a Ctrl+Drag from one view controller in the document outline view to a second view controller.
Then you will need to name the segue that is created by clicking the Segue in the middle of the gray line connecting the two view controllers and update the segue id in the identity inspector.
In your source view controller you should be able to have any action call [self performSegueWithIdentifier:#"MySegueID"];
Additionally, you can add a prepareForSegue method to the source view controller, which allows you to initialize and pass information to the target view controller.
Apple has a sample project that you can download to see this workflow in detail (MultipeerGroupChat)
Hope this helps.

Modal UINavigationController hides although not dismisses

Okay, so I'm building an universal iOS app with an initial login view (view controller named LoginVC), just a plain simple UIViewController. If the login is successful the app segues to an navigation controller (MainNavigationVC). I created this segue through the storyboard gui of XCode, so no programmatic creation of the nav controller is done. The nav controller is presented modally in fullscreen, so the rest of the app is run atop the login view, with this nav controller as the centerpiece of everything.
The navigation controller contains a view (with a view controller named UserStartPageVC), and in its navigation bar is a logout button. This button sends an target action to UserStartPageVC, with the goal of dismissing the nav controller thus bringing the user back to the login view.
So far everything works fine. I can login and use the app as intended. But! When I log out and then re-login XCode tells me this:
Warning! Attempt to present <MainNavigationVC: 0x753110> on
<LoginVC: 0x756fcf0> while a presentation is in progress!
I suppose this means that the login view is trying to modally display a MainNavigationVC navigation controller, but another one is already displayed, right? But how? Can a view be presented without showing?
And how can I get rid of the old nav controller when logging out? I've tried several ways of dismissing the modal view, for instance:
from within UserStartpageVC running
[x dismissViewControllerAnimated:YES completion:NULL]
[x dismissModalViewControllerAnimated:YES]
where x is either self, self.parentViewController or self.presentingViewController.
setting the LoginVC as a property in UserStartpageVC and running
[self.loginVC dismissViewControllerAnimated:YES completion:NULL]
and so on.
All of the tested calls actually brings me back to the login screen, so it's kind of working.
Any ideas? Relevant code samples can be provided if necessary, I just couldn't figure out which pieces that were of interest. The seguing to the navigation controller has no code (except for a performSegueWithIdentifier:sender:), and the code for dismissing it is the part I cannot seem to get straight.
As a sidenote. So far this isn't a REAL problem; the app runs, and it IS possible to logout and re-login without any other side-effects than an error message in XCode. But I suppose this will be a memory leak if users logout and login multiple times, and I'm not in the mood of an unnecessary rejection from Apple.
I discovered another way to get the exact same error message. Lucky me!
If you created a segue at one point and had it tied to a button (click button -> new view) and then later give that segue a name and invoke it directly using
[self performSegueWithIdentifier:#"identifierName" sender:self];
then you can get this error because you can effectively trigger the segue twice. I thought making the button invoke an IBAction would turn off the segue I had set up in the first place, but apparently not. Hitting the button triggered the segue twice, but after I deleted the segue and re-created it as a manual segue on the view with the same identifier then I was able to invoke it via the above code and not get the warning message.
Hoopla! My bad.
Seemed I had set up the notification observing from the login API call in a stupid way. For every time the user triggered a login (or re-login), it added itself as an observer for the notification; the result was that it performed one more segue for every time a login was done.
And doing multiple segues at the same time, is... well, obviously bad.

Increasing number of living Views

I've set up a really simple project using storyboards including two views as shown here: http://i.stack.imgur.com/iRx21.png. The navigation can be done by either selecting a cell in the custom table view or hitting the back button labelled with "<<". Everything works fine except the following:
when I switch between the views, every time an instantiation happens. The profiling shows an increasing number of view objects. I would like to keep only one of each view and instantiation should be happen only once. What am I doing wrong? (I'm using ARC.)
Thanks in advance!
You should not link your back button to the parent view controller. This is what causes the new instantiation.
The way to go is to embed the table view into UINavigationController (in IB, choose Editor -> Imbed In -> Navigation Controller. Then change your segue to a Push segue. You can of course hide the navigation bar etc. to make things look exactly as you like. Then, link the back button to the controller with an IBAction and in the handler do a simple
[self.navigationController popViewControllerAnimated:YES];
This would be the appropriate logic of what you are doing. Of course, you can also push the web view modally and then handle the button click with
[self dismissModalViewControllerAnimated:YES];

UIViewControllers problems

Hi there and thank you in advice for your help. I have a really strange problem while working with ViewControllers in Xcode4. First of all I have to say that I'm not using storyboards and I prefer to create any UI element programmatically. So I've set a UIButton and I want that, when pressed, it brings me to a new view controller. This is the code I'm using for a button:
-(void)settingsAndExportHandle:(UIButton *)buttonSender {
SettingsViewController* settingView = [[SettingsViewController alloc] initWithNibName:#"SettingsViewController" bundle:nil];
settingView.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:settingView animated:YES];
}
This buttons is initialized and allocated in the viewDidLoad method of the RootViewController. I want to switch to the other view controller (in this case SettingsViewController) when I press the button.
The strange thing is that when I press the button, the animation that flips the controllers goes well, but when it finishes I obtain the EXACT same things that I had on the RootViewControllers (same custom views, same buttons, same all!). The question is: what I'm missing?? I have to say that I use ARC (automatic reference counting) so I can't release or dealloc the views and buttons I've created on my RootViewController.
Any help will be appreciated. Thank you all!
Pushing and and modally presenting view controllers does not deallocate the view controller that presented them. It simply adds the additional view controller to the stack. You'll need to implement a callback method so that when the user hits the button to flip back to root view controller, your settings view controller lets the root view controller know what's about to happen so you can call a method you've written to reset the interface back to whatever state you need it at. You may also be able to use viewWillAppear: but that's a little messy.
However, according to the Apple Human Interface Guidelines, the user expects that when they push a view controller or modally present it, the view controller they were on will save state and be exactly the way they left it when they came back. It's disconcerting and annoying when state is not preserved while in a navigation controller context. It is especially annoying when it's modally presented.
Think about this - A user is in a hypothetical Mail app. They start typing out an email and set a font size and a color. They tap on the add attachment button, which brings up a modal view controller that allows them to select a picture. They select the picture and the modal view is dismissed, and in your implementation, the mail composing interface would have reset and the email content would be gone or at the very least the selected font size and color would be back to the default. That's not a good experience.

How do I create a UINavigationController with a default "back" state?

I have a UINavigationController, complete with table view and associated magic.
The data I'm populating that table view from may have items from multiple categories, but the default view for the user will be one in which they are viewing all of the items, and then they have the ability to move backwards to a different table view that would allow them to select a different category, which would then return to the original table view with the appropriate data populated.
What's the proper approach for this? I can't seem to wrap my head around how I would make the navigation controller give me a back button (with appropriately wired up actions) without having come from a previous view in the stack (which wouldn't really exist at launch time if I start the user off from what is essentially the detail view, in stack terms.)
Also, the back button should be titled "Groups", not "Back", but that's really just an implementation detail. :)
Update: This issue finally manifested itself in production code, and here’s how I fixed it:
My UINavigationController is created in a nib, with the root view set as the “groups” view. Then, in my app delegate, I push the second view onto the stack while the app is launching.
That works fine for achieving the proper stack, but that doesn’t help with the back button title, because the navigation controller didn’t seem to want to grab the title from the root view, and instead was showing a back button with “Item” as the title.
So, on the pushed view, in viewDidLoad, I set:
self.navigationController.navigationBar.backItem.title = #"Groups";
and that did the trick.
The only potential downside of doing it this way would be if the pushed view controller were ever used in a scenario where the view below it wasn’t the groups view, but since the design of this particular application ensures that never happens, I’m accepting that failure. ;)
Another update:
I’m an idiot. Just set the title property of the navigationItem provided by the navigationController in Interface Builder, and boom, no issue. Or do it in code. It doesn’t matter, just don’t do it by setting the backItem.title way I show you above. That’s just dumb.
In your application delegate's .m file in the application:didFinishLaunchingWithOptions: method just push your view controllers like you normally would with[self.navigationController pushViewController:your_view_controller animated:YES]; and it should push them on before the application's first view controller appears.
To change the text of the button to Groups just call this before pushing your controllers.:
UIBarButtonItem *newBackButton = [[UIBarButtonItem alloc] initWithTitle: #"Groups" style: UIBarButtonItemStyleBordered target: nil action: nil];
[[self navigationItem] setBackBarButtonItem: newBackButton];
[newBackButton release];