Crash when calling performSegueWithIdentifier with verified segue identifier string - objective-c

I added a "Done" button to my navigation bar programmatically since I couldn't do it on the storyboard.
Next, I wanted to link from this "Done" button to another subclass of UICollectionViewController (both destination and source view controllers are subclasses of UICollectionViewController).
Since, my "Done" button couldn't show up on the storyboard (because added programmatically), I created a new "Done" button on the storyboard just in the purpose of being able to generate a segue identifier between the two view controllers. I assigned the string "donePressed" to the segue identifier as you can see here: https://www.dropbox.com/s/8sd936ml1iably3/donePressed_segue_identifier.png
When I run my build, it succeeds but when I tap on the "Done" button in my navigation bar, I get the following error message: https://www.dropbox.com/s/r5fdg9xs886hxod/Error_Message_performSegueWithIdentifier.png
In essence, it is telling me that my source view controller has no segue with the "donePressed" identifier.
This is weird to me since I purposely created the segue and when I double check my code calling the "performSegueWithIdentifier" method, it looks like I have entered the right "donePressed" NSString.
See here this line of code:
-(void)donePressed {
//segue to other VC
[self performSegueWithIdentifier:#"donePressed" sender:self.doneButton];
}
What am I doing wrong?
Any help much appreciated.
Merci!

The segue you have created looks like it is from your "Done" button to the next ViewController, not from self (primary view controller) to your next view controller. If you have linked the "Done" button to perform the segue all in storyboard, you should not need to write any programmatic code to perform the segue.

Related

popping ViewController into NavigationController

I have a navigation controller, root - tabViewController, and i have one more ViewController, it isn't in Navigation controller, there is in ViewController - button.
How can i do on Clicking this button new viewController pops in current Navigation controller?
After a long series of comments ... How you are using this app couldn't be more different than the original question.
You need to replace the PKRevealController front viewController when the button is clicked something like this:
[self.revealController setFrontViewController: newViewController];
I have try to understend your question but i dont know if its that what you need:
Place a button in your firstViewController
move your mouse on that button and hold "ctrl" key
drag to the next view controller and choose push option
That's it!

UIStroyboard segue issue

I created story board App. Actually I have issuw with segue. I have one "A" view controller, and segue is suppose to push "B" viewcontroller. In "A" viewController, we are expecting some userInfo and we are performing some validations for that, and based on validation only it should push new viewController through segue. My issue is, I used triggered segue and it always push "B" view controller. Can you please inform me based on validations, how can I disable segue.
Connect the button from Scene A. Not from a UI Element on Scene A, but from the base view of Scene A.
Now, in Scene A's view controller, if you've got a button that's supposed to validate, just use an if or whatever. If all the info is good, call the segue, if it's not, don't call the segue.
Call the segue like this:
[self performSegueWithIdentifier: #"MySegue" sender: self];
Where #"MySegue" is replaced with the name you gave your segue on the storyboard.
For example:
- (IBAction) myButtonPress:(id)sender {
//validate the info
if(valid) {
[self performSegueWithIdentifier: #"MySegue" sender: self];
} else {
//probably prompt the user that their info is invalid
//maybe clear textboxes, etc.
}
}
They key here though is attaching the segue from the viewController, and not from the button itself. You also have to be sure to name your segue, and be sure the name on storyboard matches the name in code. XCode won't help you autocomplete it.

Pushing a navigation controller is not supported- performing segues

I created a new navigation controller in my storyboard (not programmatically!) and set it to be "Root View Controller" to a regular UIViewController and added a button in it which says- forward to the next view controller (this second view controller is a view controller which I want that will have a back button to link to the initial view controller).
Now, whenever I try to link the button to the next view controller- "Pushing a navigation controller is not supported".
Help me please, and thanks
EDIT:
I accidentally subclassed UINavigationController, and not UIViewController in my class.
Thank you anyway.
I've tried this and have no problems, its all done in IB with no additional code required ...
Start a new project, "Single View Application" using story boards
Select storyboard and delete the views its produced.
Drag on a new Navigation Controller (it will bring a table view with it)
Delete the table and the table view controller, so you are just left with the Navigation Controller
Drag on a normal view controller
Right Click and drag from the Navigation controller to the new View and choose "Relationship - Root View Controller"
Drag a "Bar Button Item" on to the Navbar which should be visible on the top of your ViewController, you can rename this Forward if you wish.
Now drag on another view controller which is the one your "Forward" button will push in to view.
Right Click and drag from the bar button to the 2nd View Controller, and choose "Push"
Run the project and you will get a Single view with a Navbar and your button, clicking your button will Push the other view and give you a Back Button to return to the first View Controller. I'll try and post a picture of my storyboard if it helps.
Plasma
I had the same trouble. I wanted to have a navigation controller on each storyboard, so that each could run independently, be individually debugged, and so that the look would be right with the navigation bar.
Using other approaches, I found the UINavigationController would be retained from the original storyboard -- which I didn't want -- or I'd get errors.
Using the AppDelegate in your view controller to set the rootViewController worked for me (borrowing segue naming conventions from Segue to another storyboard?):
- (void)showStartupNavigationController {
NSLog(#"-- Loading storyboard --");
//Get the storyboard from the main bundle.
UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:#"Startup" bundle:nil];
//The navigation controller, not the view controller, is marked as the initial scene.
UINavigationController *theInitialViewController = [storyBoard instantiateInitialViewController];
NSLog(#"-- Loading storyboard -- Nav controller: %#", theInitialViewController);
//Remove the current navigation controller.
[self.navigationController.view removeFromSuperview];
UIWindow *window = [(AppDelegate *)[[UIApplication sharedApplication] delegate] window];
window.rootViewController = theInitialViewController;
To swap views Programatically you would need to select the segue and give it an Identifier like "PushView" then call it like this ....
[self performSegueWithIdentifier:#"PushView" sender:self];
That will programatically do the same as clicking the forward button. I've created you an example project with the code discussed above. Has an -(IBAction) with code in you can use for programatially changing the view.
PushView.zip
I also wanted to do this, present a screen (that had an embedded navigation controller) when the user pushes a button.
At my first attempt, I connected the segue from the button in the fist screen to the Navigation Controller, and the app was crashing with this error "Pushing a navigation controller is not supported".
This is the solution I found:
Select the segue from the button in the first screen to the navigation controller.
If it had an identifier, copy its name. Then delete that segue.
Then create a new segue by CTRL-clicking the button in the first view controller and dragging to the VIEW CONTROLLER YOU WANT TO PRESENT (not to the Navigation Controller that is pointing at it), and select Push in the small pop up window.
Then click the icon in the middle of the segue and paste the name you copied in the first step as an identifier for it.
IB is going to give you a warning "Scene is unreachable due to lack of entry points and does not have an identifier for runtime access via -instantiateViewControllerWithIdentifier:." Don't worry, it works perfectly.
If you want to customize the string that is shown as the Back button to return, you can add this line in the viewDidLoad method OF THE VIEW CONTROLLER THAT IS BEING SHOWED AFTER THE BUTTON IS PRESSED, that is the Child view controller.
(replace "Settings" with the name you need)
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationController.navigationBar.topItem.title = #"Settings";
...
}

Why is it that my UITableViewController setEditing:animated: method is not called?

I must be doing stupid, but I can't see what: my UITableViewController subclass is never called when the edit button of my navigation is pressed.
What could be causing that?
My view hierarchy is loaded from a Nib file and put inside a popover. The [+] button is connected to the insertNewObject action of my UITableViewController subclass. It works fine.
The [Edit] button however has no action to connect to. The doc says it will automatically call the setEditing:animated: method of the view controller, which I override.
The nib file is set up pretty much as usual AFAICT. And in fact, I'm not sure what additional detail I can give that would suggest my mistake.
What is the control flow from the click on the [Edit] button to the call of the setEditing:animated method?
I feel like we must be missing the same thing.
Whatever the case, I made it work by doing the following.
IBOutlet UIBarButtonItem *editButton;
-(IBAction)editButtonPressed:(id)sender {
[self setEditing:YES animated:YES];
}
- (void)setEditing:(BOOL)editing animated:(BOOL)animate
{
if(self.tableView.isEditing)
{
self.editButton.style = UIBarButtonItemStylePlain;
self.editButton.title = #"Edit";
}
else
{
//self.editButton.style = UIBarButtonSystemItemDone;
self.editButton.style = UIBarButtonSystemItemEdit;
self.editButton.title = #"Done";
}
// Toggle table view state
[super setEditing:!self.tableView.isEditing animated:animate];
}
I hooked the editButton up to the button I added to the nav bar and it's action to the editButtonPressed IBAction. After doing that my setEditing: is called (obviously) and the super call toggles the table view's editing state.
I'd like to use the system defined button styles, but the appropriate one is commented out because while it did change style I couldn't figure out how to change the text from "Edit" to "Done" so I had to do it all manually (that only worked if I left the button as Custom and set the style generically). This has the downside of not being localized (for free), etc.

UINavigationController Push Views

Sorry - this may be an easy question, I'm new to iPhone development and still wrapping my head around Views vs ViewControllers.
I have a NavigationViewController and I can push Views using the following method in the RootViewController which is connected to a Bar Button Item:
- (IBAction)switch:(id)sender {
NSLog(#"Swith...");
LibraryViewController *varLibraryViewController = [[LibraryViewController alloc] initWithNibName:#"LibraryViewController" bundle:nil];
[[self navigationController] pushViewController:varLibraryViewController animated:YES];
}
I want to call this same method from a button on the same view that is currently loaded. Basically I want to have the Bar Button at the top call the same method as a button on the view. I was wondering how to call a method in the ViewController from the view loaded from that viewController. Hopefully that makes sense.
Do I need to create an instance of the RootViewController? I would think that would already be instantiated. Thank you.
BTW, the code you have pasted there is leaking your LibraryViewController. You need to either explicitly release it after pushing it, or autorelease it when it's created.
Your RootViewController should have its own xib file. In this xib, the RootViewController is represented by the object named "File's Owner". You can link buttons on the view to File's Owner the same way you can link things to RootViewController in MainMenu.xib.
You'll want to declare your method as an IBAction in your header file:
- (IBAction) myMethod: (id) sender;
Save your header, then switch to Interface Builder. Right click on the Bar Button, and drag from the selector tag to your view controller object (probably the File Owner). When you release, you should be given a popup menu of available actions, and myMethod should be selectable.
If you don't get this popup, you may need to make sure your File Owner class is set properly: select the File Owner in the file window, then select "Tools" > "Identity Inspector" from the menu. In the inspector, type your view controller's class into the Class field.