Show EditViewController while editing, show DetailViewController when not editing - ios

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.

Related

Pass data from UICollectionView in Segue

I have a UICollectionView that segues to a Detail VC. The segue goes from custom cell to the detail.
I read here stackoverflow link that you can't use prepareForSeguethat you must use performSeguein didSelectItem
The issue is, I need to pass data. I tried using prepareForSegue anyways, but the cells are now not selectable. Ideas?
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"detailSegue"]) {
LPDiaryDetailViewController *destViewController = segue.destinationViewController;
NSIndexPath *indexPath = [self.collectionView indexPathForCell:sender];
LocationImage *image = self.savedItems[indexPath.row];
NSLog(#"collectionView imageview %#", destViewController.thumbnailView);
destViewController.usernameLabel.text = [image valueForKeyPath:#"user.username"];
destViewController.locationLabel.text = [image valueForKeyPath:#"location.name"];
destViewController.captionString = image.caption;
}
}
Then I tried this with performSegue in didSelectItem and I created a method createLocationImageto call the detail VC to make a LocationImage in it's implementation, but the createLocationImage never gets called
-(void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
LocationImage *testImage = (LocationImage*)self.savedItems[indexPath.row];
[self.diaryDetailVC createLocationImage:testImage];
[self performSegueWithIdentifier:#"detailSegue" sender:self];
}

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.

Pushview on didselectrowatindexpath in storyboard

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.

Converting a line of code to be compatible with storyboards in XCode 4.3

For an IOS project I am using MWFeedParser to essentially create an RSS reader.
I am populating a tableview with the RSS feed and now want to create that segue using story board.
I can't seem to get it working. I'd normally would use didSelectRowAtIndexPath to push the detail view.
Help is much appreciated..
Thanks
This is what I'd normally do:
#pragma mark -
#pragma mark Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Show detail
DetailTableViewController *detail = [[DetailTableViewController alloc] initWithStyle:UITableViewStyleGrouped];
detail.item = (MWFeedItem *)[itemsToDisplay objectAtIndex:indexPath.row];
[self.navigationController pushViewController:detail animated:YES];
[detail release];
// Deselect
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
}
I've wired up my views and the segue in Stroyboard. My identifier for the segue in question is: ShowSelectedFeed
You could create a new Master-Detail-Application and use it as a reference. It uses exactly that pattern.
If you have created the segue in the storyboard you want to use prepareForSegue:sender: to pass your data. Something like this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSDate *object = [_objects objectAtIndex:indexPath.row];
[[segue destinationViewController] setDetailItem:object];
}
}
That's directly from the Master-Detail-Application template. Adjust it to your needs

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