Pushview on didselectrowatindexpath in storyboard - ios

I have a tableview added as a subview in one of the viewcontrollers in storyboard. It has 6 sections each having one row. On selecting each row a new viewcontroller should open. There are 6 such different viewcontrollers for that. I dont know how to achieve this in storyboard. Is there any way to bind this via storyboard or i have to do this manually. Any help will be accepted.
Thanks.

Use performSegueWithIdentifier method when you take view controllers in story board.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section==0) {
[self performSegueWithIdentifier:#"first" sender:nil];
}
if (indexPath.section==1) {
[self performSegueWithIdentifier:#"second" sender:nil];
}
if (indexPath.section==2) {
[self performSegueWithIdentifier:#"third" sender:nil];
}
if (indexPath.section==3)
{
[self performSegueWithIdentifier:#"fourth" sender:nil];
}
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([[segue identifier] isEqualToString:#"first"])
{
friendsViewController=[segue destinationViewController];
}
if([[segue identifier] isEqualToString:#"second"])
{
secondViewController=[segue destinationViewController];
}
if([[segue identifier] isEqualToString:#"third"])
{
thirdViewController=[segue destinationViewController];
}
if([[segue identifier] isEqualToString:#"fourth"])
{
fourthViewController=[segue destinationViewController];
}
}
I think it will be helpful to you.

If you have your tableview with static cells, and all of them are placed on storyboard, then you can easily drag with ctrl button and left mouse button from every cell to needed ViewController to create the segue.

Related

Failed to push to a View Controller in iOS

I'm a very beginner to iOS development. I made a navigation application in iOS to view some details in another view when table view cell tap. I did the following code,
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
LawyerViewController *dvc = [self.storyboard instantiateViewControllerWithIdentifier:#"LawyerViewController"];
NSLog(#"%#",[self.myObject objectAtIndex:indexPath.row]);
dvc.lawyer = [self.myObject objectAtIndex:indexPath.row];
[self.navigationController pushViewController:dvc animated:YES];
}
This is going to the next view. But dvc.lawyer is not null here. It's null on Next View page.
Reading the Value in Next page
NSLog(#"%#",self.lawyer.firstName);
How can I fix this.
Thanks in Advance!
You are supposed to instantiate ViewControllers in another way, if you use storyboard segues. You need to implement prepareForSegue where you can Access the segues destinationViewController like this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"YOUR_SEGUE_NAME_HERE"])
{
// reference to the destination view controller
LawyerViewController *vc = [segue destinationViewController];
// Pass any data
vc.lawyer = self.myObject[[self.tableView indexPathForSelectedRow].row]; // Not tested
}
}

Is a prepareForSegue notify a view controller when a segue is about to preform to another view controller?

Up until now I have used prepareForSegue method to notify a view controller he is about to review a segue from a different view controller, but if i'm the vc that sending the segue, will my prepareForSegue (in he same class of the segue sender) will check if there is a code to preform before he fires the segue?
I'm asking because I got a solution here to preform a simple segue just to go from stable view row which represent notes to the creation page of the note for editing...very simple, but from some reason it's not presenting my note in the creation page, only takes me to a new clean creation page..
So I though maybe it's because the prepareForSegue method..here you can see the question to give you more details How to to create a segue to push back to editing mode from a table view?
Would really appreciate to get your help on this.
This are the 2 methods I added to my NotesList table view controller:
#pragma mark - delegate
- (void) tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"noteSegue" sender:nil];
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"noteSegue"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NMNote *note = [self.notes objectAtIndex:indexPath.row];
NMCreateNotesViewController *destination = [segue destinationViewController];
destination.textField.text = note.content;
}
}
And I made sure the segue identifier in the storyboard is named noteSegue. So why its note working...Im getting a new TextView instead of populating it with the note content :/
This is the error i'm getting:
Thanks!
The prepareForSegue: method is called on the current VC not the destination. UIViewController Class Reference. You can use the method to obtain a reference to the destination VC and set variables/call methods on it before the segue is performed.
Calling the segue like this:
[self performSegueWithIdentifier:#"NAMEOFSEGUE" sender:nil];
You can then prepare the destination VC like this:
#import "NMCreateNotesViewController.h"
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"NAMEOFSEGUE"]) {
NMCreateNotesViewController *destination = [segue destinationViewController];
[destination createNote]; /* or something similar */
}
}
EDIT:
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NMNote *note = [self.notes objectAtIndex:indexPath.row];
[self performSegueWithIdentifier:#"noteSegue" sender:note];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"NAMEOFSEGUE"]) {
NMCreateNotesViewController *destination = [segue destinationViewController];
NMnote *note = (NMNote*) sender;
destination.textField.text = note.content;
}
}
To check if there is a code to preform before the segue you can use solution below:
if ([segue.destinationViewController isKindOfClass:[UIViewController class]]) {
UIViewController *nextVC = segue.destinationViewController;
if(nextVC respondsToSelector:#selector(yourMethod)){
[nextVC yourMethod];
}
}
You can check if you are sure to perform the specific segue by implementing this method
- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender
If you have your note presenting code in viewDidLoad, try moving that to viewDidAppear (in your note editing VC). There used to be an issue when presenting from a TableView row where the segue would fire after VDL was executed.

Unwind segue seems to deallocate my view objects

I'm trying to pass an object using unwind segue. My button unwinds successfully, but all the objects in the view are reinitialized or something. I use prepareForSegue method to prepare my object successfully, but when I access the viewController in my destination segue (through an action button) all the objects are either reinitialized or not allocated.
I'm pretty new at this so any suggestions would be appreciated! Here's the code I'm stupefied with.
//prepareForSegue is called in my view controller i'm trying to unwind from.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"ReturnInput"])
{
GLUPipeDataController *dataController;
dataController.length = [[NSNumber alloc] initWithFloat:1.5];
self.dataController = dataController;
[self.dataController print];
}
}
//this done is called in my destination view controller. It is linked in IB by control-draging the unbutton to the exit routine on the connections panel. I then updated the name of the unwind segue in the document outline.
- (IBAction)done:(UIStoryboardSegue *)segue
{
if ([[segue identifier] isEqualToString:#"ReturnInput"])
{
GLUEditViewController *editController = [segue destinationViewController];
if (editController.dataController)
{
self.dataController = editController.dataController;
[self.dataController print];
[[self tableView] reloadData];
}
}
if ([[segue identifier] isEqualToString:#"ReturnInserts"]) {
GLUEditInsertsViewController *editInsertController = [segue destinationViewController];
if (editInsertController.listInserts) {
self.dataController.listInserts = editInsertController.listInserts;
[[self tableView] reloadData];
}
}
}
The call [self.dataController print] in prepareForSegue prints property. But the same call in the done method prints a newly initialized object.

Show EditViewController while editing, show DetailViewController when not editing

I do have a UITableViewController which can be edited.
I do have 2 Segues in my Storyboard, coming from the tableView going to an EditViewController (via modal) and the second one via Push to the DetailViewController.
I want, when the tableview isEditing, that the segue to editviewcontroller is executed, and when is not editing, than to DetailViewController.
I tried different ways, with the prepareforsegue method. then several tries with the didselectrowatindexpath method, where I stand now.
Now, when the tableView is in editing and I touch one cell, the detailviewcontroller pushes and on top of this the editviewcontroller comes in as modal view controller.
Here is my code.
Can you please give me hints:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(#"didSelectRowAtIndexPath %i", indexPath.row);
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
if (tableView.isEditing == FALSE) {
NSLog(#"isediting");
[self performSegueWithIdentifier:#"showDetail" sender:cell];
} else {
[self performSegueWithIdentifier:#"showEditPerson" sender:cell];
}
}
and here is what i have tried with the prepare for segue method:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSDictionary *theChild = [myAppDelegate.myPersonsArray objectAtIndex:indexPath.row];
[[segue destinationViewController] setDetailItem:theChild];
}
if ([[segue identifier] isEqualToString:#"showEditPerson"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSDictionary *theChild = [myAppDelegate.myPersonsArray objectAtIndex:indexPath.row];
[[segue destinationViewController] setDetailItem:theChild];
}
}
From my comment above:
It seems you have the prototype cell hooked up to a segue in addition to the delegate method. Fix the segue connections and you should be all set.

iOS - UIStoryboardSegue detecting table cell and opening a viewController?

So I have a UITableView, and the cells are connected to a UIStoryboardSegue in order to open a new UIViewController. After clicking a cell prepareForSegue get's called and everything works fine.
QUESTION: In the follwoing method how can i know what is the indexPath of the selected cell in my TableView?
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
ObjectDetailViewController *mvc = [segue destinationViewController];
// PassingObject *obj = [self.array objectAtIndex: ? ];
mvc.passingObject = obj;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Assume self.view is the table view
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
DetailObject *detail = [self detailForIndexPath:path];
[segue.destinationViewController setDetail:detail];
}
Instead of [self.tableView indexPathForSelectedRow] (look at the DJPlayer answer) you can use [self.tableView indexPathForCell:sender], since sender is a selected cell in this case.

Resources