I am trying to segue from one UIViewController (VC1) to a UITableViewController (VC2) and I have tried all the usual suspects. Other posts did not seem to find a solution
In the Storyboard I created a modal segue from VC1 to VC2 and give it the identifier "VC2Segue".
Clicking VC1's connections properties shows a 'Storyboard Segue': modal--VC2.
Clicking VC2's connections properties shows a 'Referencing Story Board Segue': modal--VC1
In VC1 I have a UITableViewDelegate method that responds to cell selections in VC1. This is where I attempt to segue to the details view (VC2):
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
[self performSegueWithIdentifier:#"VC2Segue" sender:self];
}
However, as soon as performSegueWithIdentifier is called I receive an exception:
'NSInvalidArgumentException', reason: 'Receiver (VC1) has no segue with identifier 'VC2Segue''
In case it is relevant. VC1 inherits from an external proprietary library (Parse.com: PFQueryTableViewController) which appear to instantiate a `UITableView'. Hence the UITableView does not show TableCells on the Storyboard, instead VC1 is a delegate of UITableView, which which is how VC1 (A UIViewController) accesses the above method.
I've tripled checked the connections, cut and pasted the text fields, ensured that the storyboard nibs point to classes VC1 and VC2 respectively, and tired both push and modal. I'm clearly missing something, but this is my first tour of duty with iOS.
Related
I have a viewcontroller with multiple tableviewcells in it. I want move from one of the tableviewcell to another viewcontroller using storyboard. I have a navigation controller for viewcontroller. I didn't really find a way to solve this.
You should implement didSelectRowAtIndexPath delegate, then some logic for move to another view controller.
#interface ViewController()<UITableViewDelegate>
...
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
AnotherViewControllerClass *vc = [[UIStoryboard storyboardWithName:#"StoryboardNameOfAnotherViewController" bundle:nil] instantiateViewControllerWithIdentifier:#"AnotherViewControllerIdentifier"];
[self.navigationController pushViewController:vc animated:YES];
}
if you want to do with storyBoard then you can use Segue to jump from one tableview cell to another ViewController what you have to do is
1). right click and drag from your table view cell to your desired view Controller and then release it you would see a pop up select "show"
2). click the segue and go to identity inspector and name the segue identifier as you wish
3).then you have to just write a method prepareFor segue methodand in that write if statement like this
if (segue.identifier == "your identifier Name")
{
//`enter code here`write your logic of pushing the viewcontroller
}
the above code for if is in swift and you can repeat the steps for your all multiple tableviewcell with diffrent identifier name
if not using storyboard then use this method
if (indexpath.row == 0)
{
//use the push viewcontroller code here
}
for each index path you can check and push diffrent viewcontrollers
Try this..
Open Storyboard and select your initial view controller
Select editor from top bar menu in your Xcode
Select Embed in and choose UINavigationController
And run your code again...
I have a custom tableview cell in xib file. I am using this custom cell in my FirstViewController. I want to show SecondViewController on didSelectRowAtIndexPath of first viewController.
And I am performing segue in didSelectRowAtIndexPath like
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"secondViewControllerSegue" sender:indexPath];
}
I am getting error saying -
'Receiver () has no segue with identifier 'secondViewControllerSegue''
What am I missing here?
Go to your storyboard and Ctrl+Drag from the first view controller (the yellow icon of the first view controller) to the second to create a segue. Then on the left panel go to attributes inspector tab and set an identifier for your segue. Then just set the same identifier in your performSegue method.
You have to connect a segue from firstViewcontroller to secondviewcontroller with the name you are using for segue.
And stroyboard id is not for segue it is for identifying controller in the the storyboard.
You have to create segue between you first and second view controller the rest of you code is fine.
In my UITableView, when a user taps on a cell I initiate a segue like so:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"MCExpandedSegue" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"MCExpandedSegue"]){
// Opens item in browser
MCExpandedViewController *controller = (MCExpandedViewController *) segue.destinationViewController;
}
}
In order for the destination view controller (MCExpandedViewController) to have a navigation bar and a back button, I've embedded it in a Navigation Controller like so:
However, upon tapping a cell in the table in order to make this segue, I get the following error: *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Pushing a navigation controller is not supported'. Is this because it tries to segue to MCExpandedViewController but gets tripped up because it's contained within the navigation controller? How can I do this segue correctly?
Remove the navigation controller and segue
MCExpandedViewController directly.
Add this to viewWillAppear: in MCExpandedViewController.m
[self.navigationController setNavigationBarHidden:NO animated:YES];
First make sure your first view controller is embed in navigation controller.
MatchCenterViewController is in navigation controller.
No need of another navigation controller in different scene.
I am trying to push a table view controller that I have on my storyboard from a view controller that I don't have in my storyboard. I get these errors when i get to initializing the first table view cell. I've made sure the table view controller and the table view cell are set to the correct class types that I've defined and I've set the correct identifier for the cell.
Error Occurs at Line:
CustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ListPrototypeCell" forIndexPath:indexPath];
Error:
*** Assertion failure in -[UITableView dequeueReusableCellWithIdentifier:forIndexPath:], /SourceCache/UIKit_Sim/UIKit-2935.137/UITableView.m:5439
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier ListPrototypeCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
What am I missing?
P.S that other link does not have the answer, I need to initialize multiple cells of this type, I need the index for different data.
Why not just put all the view controllers in one storyboard?
If you're trying to push from a UITableViewCell, you could use a segue method.
First: Control-Drag from your TableViewController to your ViewController to link them with a push segue. Name the segue. E.G. "segueName"
Create a prepareForSegue method like so:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"segueName"])
{
// do whatever you want here
}
and then under your didSelectRowAtIndexPath:, run the segue using this:
[self performSegueWithIdentifier:#"segueName" sender:nil];
Perhaps you could elaborate a bit more, if this does not work.
I have a problem,
The following is my StoryBoard,
the first Controller is a TabBarController,
and it relation with A (ViewController).
A is a ViewController,
B is a NavigationController, A change page to B by modal segue
C is a ViewController, C will change to another page by push so I need a NavigationController
OK, I want to pass value from A to C,
now I can pass value from A to B by prepareForSegue,
However, because B and C have relationship but not segue,
So I can't pass value from B to C by prepareForSegue!!!
How can I pass value between NavigationController and ViewController with StoryBoard?
The Storyboard image is a little misleading here.
When you segue to B, actually you are segueing to the B/C combo as NavControllers always have at least one viewController in their stack (which is their topViewController and their [viewControllers objectAtIndex:0]).
So you do have a relationship directly from A to C.
How you access that controller depends on whether your segue is modal or push. In your case it is modal, but I will describe both so you can see the difference.
In either case, to pass data to C, you need to declare a property in it's header file
#interface CviewController: UIViewContrller
#property (assign) int dataFromA;
#end
push segue
In a push segue, it is actually C that is the destinationViewController, not B. In fact the push segue is governed by B, which is the UINavigationController for both A and C. The code behind the push segue is of the form
[self.navigationController pushViewController:otherViewController];
In AviewController's prepareForSegue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
CviewController* controller = segue.destinationViewController;
[controller setDataFromA:self.data];
}
It is possible in the storyboard to make a push segue line between two viewControllers that do not share a common UINavigationController. However when you run this you will get a crash error:
'Could not find a navigation controller for segue 'pushC'. Push segues can only be used when the source controller is managed by an instance of UINavigationController.'
Behind every good push segue lies a Navigation Controller.
modal segue
The code hiding behind a modal Segue is the UIViewController method
- (void)presentViewController:(UIViewController *)viewControllerToPresent
In a modal segue to a NavController/ViewController combo, the destination viewController is whatever the segue line points to. If it points to a viewController, that is the segue.destinationController (and the UINavigationController will be ignored, which is not what you want here); if it points to a UINavigationController, as in this case, that will be it's destinationController. But it is still straightforward to access the viewController, as it will be the navigation Controller's topViewController.
In AviewController's prepareForSegue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
CviewController* controller =
(CviewController*)[[segue destinationViewController] topViewController];
[controller setDataFromA:self.data];
}
Note that in this case we have to use old-style [[message passing] syntax]. If we use modern.property.syntax we get a compile error. That's because the program does not know the type of desinationViewController, and refuses to accept topViewController as a property of an unknown type. But it is happy to [send [real messages]] to an unknown type. We also have to (typecast*) to avoid compiler warnings.