Creating and using segue to launch storyboard view via didSelectRowAtIndexPath - ios

I have a table view with cells created with:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"GalleryCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
}
NSMutableArray *gallery = [gallerys objectAtIndex:indexPath.row];
cell.textLabel.text = [gallery objectAtIndex:1];
return cell;
}
What I need to be able to do is within the didSelectRowAtIndexPath, fire a segue to launch another view, this will also send some information across using the prepareForSegue method.
This issue is I am not sure how to go about creating the segue to be used in this instance as within the storyboard I have nothing to attach it to (no buttons etc) and the cells are created within the code, is it possible to also create the segue in the code? Or is there another method to this?

Okay, you can attach it to your table view controller, it is not necessary to attach it to a button. Just go to the storyboard and do the following:
Right click on the VC that you would like to push.
Under Presenting Segues in the menu click and hold 'push' and drag it to your table view controller.
Choose manual when the dialog shows above your table view controller.
Select the segue after it appears and go to its attribute inspector.
Choose a name for the segue.
Call performSegue

simply drag a segue from your table to destination Controller and give a name for that.
And in didSelectRowAtIndexPath call
[self performSegueWithIdentifier:#"MySegue" sender:self];
then following method will get called
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// here you can pass any value to new ViewController;
if ([segue.identifier isEqualToString:#"MySegue"]) {
YourNewViewController *VC = segue.destinationViewController;
VC.data = yourData;
}
}

Push your view controller
[self performSegueWithIdentifier:#"yourSegueID" sender:self];
You can send the information as below
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"yourSegueID"]) {
YourViewController *yourVC = segue.destinationViewController;
yourVC.information = myInformation;
}
}

Related

prepareForSegue with customCell in tableview

I have a controller with a listview that contain a custom cell.
I have created a modal segue from the cell to the next controller and I gave a name to this segue but when I click on the cell, prepareForSegue isn't called.
I could use the didSelectRowAtIndexPath and performSegueWithIdentifier but I have to send data to the next controller from the cell I've clicked on.
Any idea why the prepareForSegue isn't called? Or how to send data to the controller with another method?
You can get the cell data in didSelectRowAtIndexPath by getting the cell from the index of customCell that you clicked, and after you can performSegueWithIdentifier.
So let's make this easier:
Under your didSelectRowAtIndexPath method, add this line to get the properties of your customCell
YourCustomCell *customCell = (YourCustomCell *)[self.tableView cellForRowAtIndexPath:indexPath];
So now if you have something stored under your customCell you can access it from customCell instance.
After you managed to store or manipulate your data from customCell you do the performSegueWithIndenfier:
[self performSegueWithIdentifier:#"yourSegueID" sender:self];
Hope this helps
When you connect a segue from a cell to another view controller, unless it's a static table view, you'll have to trigger performSegueWithIdentifier from the didSelectRowAtIndexPath
After you execute performSegueWithIdentifier, prepareForSegue would be called.
In prepareForSegue, you can set up your destination view controller, which you can access via segue.destinationViewController
Like so:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
[super prepareForSegue:sender sender:sender];
if ([segue.identifier isEqualToString:#"YOUR_SEGUE_NAME_HERE"]) {
UIViewController *destinationViewController = segue.destinationViewController;
}
}
Or if you need to set things up in the didSelectRowAtIndexPath , you could do (iOS7+ only)
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self performSegueWithIdentifier:#"YOUR_SEGUE_NAME_HERE" sender:self];
UIViewController *destinationViewController = [self.transitionCoordinator viewControllerForKey:UITransitionContextToViewControllerKey];
}
Update:
Turns out #rdelmar is correct, it does work with dynamic cells.
All you have to do then is
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
[super prepareForSegue:sender sender:sender];
if ([segue.identifier isEqualToString:#"YOUR_SEGUE_NAME_HERE"]) {
NSIndexPath *selectedIndexPath = [self.tableView indexPathForCell:sender];
}
}
And you have the index path of the cell that was tapped. Then you can use that to query your datasource and find the object that was used to populate that cell.

Pushing Data from UITableViewCell to ViewController

I am trying to push data from a UITableViewCell into another view controller. I have tried two separate ways, instantiateViewControllerWithIdentifier and also PrepareForSegue. In both instances the ViewController loads correctly but the data is not being passed across (either null, or the first array value).
Here is my instantiateViewControllerWithIdentifier method, when I log the variable within my ViewController it just returns null.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *testNumber = [jobNumberArray objectAtIndex:indexPath.row];
NSLog(#"Job is... %#",testNumber);
StandardInfoViewController *controller = [self.storyboard instantiateViewControllerWithIdentifier:#"StandardInfoViewController"];
controller.JobNr = [jobNumberArray objectAtIndex:indexPath.row];
[self.navigationController pushViewController:controller animated:YES];
}
Prepare For Segue
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self performSegueWithIdentifier:#"Details" sender: self];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"Details"]){
StandardInfoViewController *controller = (StandardInfoViewController *)segue.destinationViewController;
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
controller.jobNumber = [jobNumberArray objectAtIndex:indexPath.row];
}
}
When I use the prepareForSegue call I get the first row of my Array, which I understand because it doesn't know the cell, but I don't know how to identify the Cell within the prepareForSegue call.
I hope this makes sense, and any help or pointers would be greatly appreciated.
Thanks
If you drag the segue FROM the tableView-cell in the storyboard, you will then get the cell itself as parameter sender.
then you can use tableView indexPathForCell:sender to get the actual index of the selected cell. Then just fetch your object normally.
I.e. you will not need to implement didSelectRowAtIndexPath
If you still want to use didSelectRowAtIndexPath, just pass the cell as the sender parameter manually. I.e:
[self performSegueWithIdentifier:#"Details"
sender:[self.tableView cellForRowAtIndexPath:indexPath]]
Although your first version with instansiateViewController should work, judging by your code.
Another pattern is to subclass the cells themselves, and let them have a property that is the object that they want to display. Then you can just fetch the object directly from the cell without calling the data-array itself.
Is this what you want?
This is how you identify Cell in prepareForSegue method.
**UITableViewCell *cell=[myTable cellForRowAtIndexPath:path];**
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:#"Details"]){
StandardInfoViewController *controller = (StandardInfoViewController *)segue.destinationViewController;
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
**UITableViewCell *cell=[self.tableView cellForRowAtIndexPath:indexPath];**
controller.jobNumber = [jobNumberArray objectAtIndex:indexPath.row];
}
}

IOS prepareForSegue using custom tableview cell

i created a .xib with my custom cell that I'm using on one of my tableviewcontroller in my storyboard.
In the storyboard, I linked the current tableview with another tableview with a push segue. (when the user click on one of the cell, he has a new view).
The problem is, I don't understand, how to "link" this segue, with my CUSTOM cell ?
I'm loading my custom cell like that :
static NSString *simpleTableIdentifier = #"cellCustom";
cellCustomView *cell = (cellCustomView *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"cellCustom" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
and when I try to implement the method :
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSLog(#"test");
}
I've nothing, because according me, I missed something to do with my custom cell, and the segue of my storyboard, but I don't understand how it works :/
thx,
Did you try this?
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"MySegue"
sender:self];
}
This method belong in whichever class contains the tableView. Make sure that the tableView's delegate is equal to self in that class. If you're using a storyboard, control-drag this view to whichever view you want to segue to. Click on that segue, and change its identifier to "MySegue" or whatever you want, as long as its the same in your code.
You can try the following approach
Control + Drag from your cell to next view controller to setup a segue called "showDetail", that you want to show on clicking tableview cell.
and in your view controller
if you have nsarray such as
NSArray *names = #[#"Apple", #"Google", #"Microsoft"];
and you want to pass the array value based on the selected table row cell index, you can as follows
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showDetail"])
{
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSString *name = _names[indexPath.row];
// For explanation sake, I am assuming name as property defined
// in your destination view controller
[[segue destinationViewController] setName:name];
}
}

Xcode 5: How do I segue from a table view if the table view is edit-mode?

I have a simple table view that can segue to an update-view-contoller to edit that row when the user taps on a row. Issue: I would like to segue to the update-view-contoller when the table view is in "edit-mode", otherwise nothing should happen.
I am using Storyboard to create the segue linking the prototype cell to the update-view-controller.
Any idea on how to make the segue work only if the table view is in "edit-mode"?
Here is my prepare for segue code that is invoked when the user taps on a row from the table view contoller. My segue has an identerfied called "ShowUpdate":
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"ShowUpdate"]) {
UpdateViewController *updateviewcontroller = [segue destinationViewController];
NSIndexPath *myIndexPath = [self.tableView indexPathForSelectedRow];
int row = [myIndexPath row];
NSString *selectedRow = [NSString stringWithFormat:#"%d", row];
updateviewcontroller.DetailModal = #[_Title[row], _Description[row], selectedRow];
}
}
Thanks for any help
How about a simple if check for isEditing property of the tableView?
#property(nonatomic, getter=isEditing) BOOL editing
Instead of making a segue from a prototype cell, I would drag it from the ViewController itself, and then check the above property in the didSelectRowAtIndexPath: delegate method and perform the segue in code from there.
Plus, you would need to set allowSelectionDuringEditing property somewhere in viewDidLoad or so.
self.tableView.allowsSelectionDuringEditing = YES;
Code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (self.tableView.isEditing) {
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
[self performSegueWithIdentifier:#"ShowUpdate" sender:cell];
}
}
Segue construction:

tableview to detailviewcontroller storyboard issue

Here's my problem. I have data being passed into the 'second view controller' by mySQL which currently works great. But when I select on any of the from (UITableView) cells, I am currently not able to open a new view to show the data.
I believe the code issue is with
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
detailedViewController *productinfo = [self.storyboard instantiateViewControllerWithIdentifier:#"productDetails"];
//Retrieve current user array
foodProducts *currentProduct = [bakeryProductArray objectAtIndex:indexPath.row];
productinfo.productName = currentProduct.productName;
productinfo.productImage = currentProduct.productImgUrl;
productinfo.productDescription = currentProduct.productDescription;
[self.navigationController pushViewController:productinfo animated:YES];
}
There have been others who have over came this using nibs but not storyboard.
Can someone point out where I have gone wrong or something I have fundamentally missed?
(I have another project which fully working with navigation controller only. Though this is the 1st project which I have tried to use with the tab bar navigation).
The best way to handle this with a storyboard is to create a segue to the detail view from your mainViewController. This can be from your actual cell or from the controller. In your prepare for segue method, pass the object to the detail view. This uses a fetchedResultsController but the idea is the same. Get the selected cell and pass the object to the detail view.
Here is a sample of how you could pass it while using a segue from the cell itself. Create a segue from the tableViewCell in IB for "selection". Drag that segue to your detailViewController and set the identifier to ShowDetailView then add the following prepareForSegue method.
Make sure to have a property (foodProduct) on your detailViewController that will hold the reference to your selected object. That's what you will pass from your mainViewController.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"ShowDetailView"])
{
DetailViewController *detailViewController = [segue destinationViewController];
foodProducts *currentProduct = [bakeryProductArray objectAtIndex:[self.tableView indexPathForSelectedRow]];
detailViewController.foodProduct = currentProduct;
}
}
try this .....
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
Decriptionview *detail = [self.storyboard instantiateViewControllerWithIdentifier:#"Decription"];//#"Decription" is Storybord Id of UiViewController of Decriptionview
detail.wndecDecription=[SortedDecription1 objectAtIndex:indexPath.row];
detail.wndectitle=[SorttedTitle1 objectAtIndex:indexPath.row];
detail.wndeclink=[SortedLink1 objectAtIndex:indexPath.row];
detail.wndecdate=[SorttedDate1 objectAtIndex:indexPath.row];
detail.imgeurl=[sorttedMainImage1 objectAtIndex:indexPath.row];
[self.navigationController pushViewController:detail animated:YES];
}

Resources