UiTableview Sequeing with didselectrowAtindex returns previous selection? - ios5

i hope someone can please help me with this. Im doing something really wrong here. Im trying to seque to a detailview. The problem is that the first time i select it, it returns a nil value, the second, third, etc time it returns the value i selected before.
I hope someone can please help me.
Thanks a lot in advance.
Greetings,
jaco
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger section = [indexPath section];
NSArray *HS = [sect objectForKey:[alles objectAtIndex:section]];
passString = [HS objectAtIndex:indexPath.row];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
SiTDetailViewController *vcTarget = [segue destinationViewController];
vcTarget.mijnString = passString;
}

hehe...figured it out. was kinda silly of me the ' delay' was because i used both seque and didSelectRowAtIndexPath.
This is how it worked fine:
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
NSIndexPath *path = [self.tableView indexPathForSelectedRow];
NSArray *HS = [sect objectForKey:[alles objectAtIndex:path.section]];
passString = [HS objectAtIndex:path.row];
SiTDetailViewController *vcTarget = [segue destinationViewController];
vcTarget.mijnString = passString;
}

Related

How do I utilize CoreData when moving from collection view to detail view

I have an IOS app that is using RestKit to pull json formatted data from a server into a CoreData Entity. Some of the attributes of the entity help populate a collection view with an image and title for each cell.
I am attempting to move from the collection view to a detail view when a cell is selected. There is a "summary" attribute of the CoreData Entity that I would like to display in the detail view along with the image.
I know I can pass data thru the prepareForSegue method. But I am not sure how to specify the image and summary data I want to pass.
Maybe passing the image and summary is not the proper way? Should I be passing the managedObjectContext to the detail view controller and fetching the results from there?
Here is how my CollectionView is populated.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
MyNewsCollectionViewCell *cell = (MyNewsCollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath];
NSManagedObject *object = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSURL *photoURL = [NSURL URLWithString:(NSString *) [object valueForKey:#"imageUrl"]];
NSData *photoData = [NSData dataWithContentsOfURL:photoURL];
[cell.cellimg setImage:[[UIImage alloc] initWithData:photoData]];
[cell.title setText:[object valueForKey:#"title"]];
return cell;
Here is the prepareForSegue method
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"newsDetail"]) {
NewsDetailViewController *vc =[segue destinationViewController];
vc.newsDetailImageView = //How do I designate the image from the cell I selected???
vc.newsDetailText = //How do I designate the text from the cell I selected???
}
}
This is obviously a beginners question.... any help would be much appreciated. Given that I'm a beginner basic example code really helps!
If the cell selection triggers the segue instantly, you can make use of the indexPathForSelectedItems method of UICollectionView to get the indexPath that you need to get your NSManagedObject.
Try this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"newsDetail"]) {
NewsDetailViewController *vc =[segue destinationViewController];
// In the following line, replace self.collectionView with your UICollectionView
NSIndexPath *indexPath = [[self.collectionView indexPathsForSelectedItems] objectAtIndex:0];
NSManagedObject *object = [self.fetchedResultsController objectAtIndexPath:indexPath];
NSURL *photoURL = [NSURL URLWithString:(NSString *)[object valueForKey:#"imageUrl"]];
NSData *photoData = [NSData dataWithContentsOfURL:photoURL];
UIImage *img = [[UIImage alloc] initWithData:photoData];
vc.newsDetailImageView = [[UIImageView alloc] initWithImage:img];
vc.newsDetailText = howeverYouGetYourObjectSummary;
}
}
You could add a property to you MyNewsCollectionViewCell, like so:
#property (weak,nonatomic) NSManagedObject* myObject;
Then you could assign this property the NSManagedObject for this cell in cellForItemAtIndexPath.
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
/* Add this line to All that u r already doing*/
[cell setMyObject:object];
return cell;
}
Now in didSelectCellMethod you can call [self performSegueWithIdentifier: #"MySegue" sender: cell];
and then in prepareForSegue: get the object from the sender.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(MyNewsCollectionViewCell)sender
{
if ([[segue identifier] isEqualToString:#"newsDetail"]) {
NewsDetailViewController *vc =[segue destinationViewController];
NSManagedObject* object = sender.myObject;
//use this object to set values of
vc.newsDetailImageView = /*set value*/
vc.newsDetailText = /*set value*/
}
}

TableView delete after I click button delete

So I am trying to delete rows in table view.
Here is my code:
- (IBAction)done:(UIStoryboardSegue *)segue
{
DetailGodsViewController *detailController = [segue sourceViewController];
NSIndexPath *path = [NSIndexPath indexPathForRow:detailController.row inSection:detailController.section];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:path]
withRowAnimation:NO];
[self.listOfGoods deleteGood: detailController.row];
[[self tableView] reloadData];
[self dismissViewControllerAnimated:YES completion:NULL];
}
I have ControlViewTable in storyBoard, after I click on a row in ControlViewTable it jumps to Detail view And there is other info, also I store info about the row and section in this function:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"ShowGoodDetails"]) {
DetailGodsViewController *detailViewController = [segue destinationViewController];
detailViewController.row = [self.tableView indexPathForSelectedRow].row;
detailViewController.section = [self.tableView indexPathForSelectedRow].section;
detailViewController.good = [self.listOfGoods getGoodAtIndex:detailViewController.row ];
}
and there is also a button in detail view for delete, after I click on it, it jumps to the function:
- (IBAction)done:(UIStoryboardSegue *)segue.
But it always crashes in deleteRows. Could someone please help?
One problem might be that you're still responding to the button while you're trying to get rid of the cell containing the button. You need to let that action method end, and then call deleteRows. You should probably do the sort of thing I recommend here:
https://stackoverflow.com/a/13907375/341994
However, the biggest problem is probably that you must update the model data before deleting a row of the table.
Your code in the done: method is doing a few things out of order plus some extra things you don't need. It should be:
- (IBAction)done:(UIStoryboardSegue *)segue
{
DetailGodsViewController *detailController = [segue sourceViewController];
NSIndexPath *path = [NSIndexPath indexPathForRow:detailController.row inSection:detailController.section];
[self.listOfGoods deleteGood: detailController.row];
[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:path]
withRowAnimation:NO];
[self dismissViewControllerAnimated:YES completion:NULL];
}
Basically, you need to update your data before you update the table. Also, don't call reloadData on the table after calling deleteRowsAtIndexPaths:. Do one or the other, not both.

How do I change a UILabel's text on a pushed (with segue) view, relative to the senders selected accessory?

I have a UITableView that pushes, via a storyboard segue, a view, which displays a UILabel that I wish to change the text on relative to the indexPath.row of the selected accessory on the UITableView.
I know it's probably wildly wrong, but this was my attempt. I feel like I'm going about it very wrong:
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"ArticlePreviewSegue" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSIndexPath *indexPath = [sender indexPathForSelectedRow];
ArticlePreviewViewController *apvc = [segue destinationViewController];
NSDictionary *article = [_newsFetcher.articles objectAtIndex:indexPath.row];
apvc.titleLabel.text = [article objectForKey:#"title"];
apvc.bodyLabel.text = [article objectForKey:#"body"];
}
Thanks you!
One problem may be that tapping the accessory doesn't select the row. You can handle that by passing the index path as the sender of the segue:
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
[self performSegueWithIdentifier:#"ArticlePreviewSegue" sender:indexPath];
}
Now you can access the index path in prepareForSegue:sender: without relying on the row being selected.
Another problem is that in prepareForSegue:sender:, apvc hasn't loaded its view yet. So apvc.titleLabel and apvc.bodyLabel are both nil.
The proper way to handle this is to give ArticlePreviewViewController an article property and set that property in prepareForSegue:sender:, like this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSIndexPath *indexPath = (NSIndexPath *)sender;
ArticlePreviewViewController *apvc = [segue destinationViewController];
apvc.article = [_newsFetcher.articles objectAtIndex:indexPath.row];
}
Then, in -[ArticlePreviewViewController viewDidLoad], you can set the labels based on the article:
- (void)viewDidLoad {
[super viewDidLoad];
self.titleLabel.text = self.article[#"title"];
self.bodyLabel.text = self.article[#"body"];
}

Segue Headaches in Xcode

I have a tableview and I created a segue to push it to another view controller. Every now an then this segue breaks without me touching it I can guarantee. I didn't even edit the file I put it in.
My Code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *acell = [tableView cellForRowAtIndexPath:indexPath];
[self performSegueWithIdentifier:#"cellWasSelected" sender:acell];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"cellWasSelected"])
{
if ([sender isKindOfClass:[UITableViewCell class]])
{
UITableViewCell *selectedCell = sender;
ViewController *myDetViewCont = segue.destinationViewController;
myDetViewCont.navigationItem.title = selectedCell.textLabel.text;
}
}
}
First after clicking a cell xcode directs me to the file this segue pushes to.
It redirects me here: action:#selector(handleSingleTap:)];
I use this for my images to trigger this: [self.navigationController popToRootViewControllerAnimated:YES]
If I choose in Thread 1 my main view I see the problem is:
[self performSegueWithIdentifier:#"cellWasSelected" sender:acell];
But whats the problem I used this athousand times and it starts crashing without me changing it.
Your code don't have any bugs, the problem is somewhere else. May be you have not give the segue an identifier in interface builder. Try this code. It is working on my side, if your files don't have any problem it should run on your side too.
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NSString* identifier = [segue identifier];
if ([identifier isEqualToString:#"cellWasSelected"]) {
NSLog(#"Performing Seque");
if ([sender isKindOfClass:[UITableViewCell class]]) {
NSLog(#"correct");
UITableViewCell *selectedCell = sender;
UIViewController* myDetViewCont = segue.destinationViewController;
myDetViewCont.navigationItem.title = selectedCell.textLabel.text;
}
}
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"%#",#"Cell Selected");
UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
[self performSegueWithIdentifier:#"cellWasSelected" sender:cell];
}
P.S. If you are still having problems you, then may be you are new to storyboard and you need enough knowledge to work on them.
http://www.raywenderlich.com/5138/beginning-storyboards-in-ios-5-part-1

update UILabel with the content of UICell from a different view

I have an NSArray tablePeople which makes up my UITableView on my 1st View Controller PeopleController. I have a UILabel personsName on my second View Controller PeopleDetailsController which I want to update with the contents of cell.textLabel.text of each row in my TableView. I have this method but it's not working:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
((PeopleController *)segue.destinationViewController).delegate=self;
if ([[segue identifier] isEqualToString:#"toPeopleArticle"]) {
NSIndexPath *indexPath = (NSIndexPath *)sender;
PeopleDetailsController *mdvc = segue.destinationViewController;
mdvc.personsName.text = [self.tablePeople objectAtIndex: indexPath.row];
}
}
I also have this code when the cell is selected:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"toPeopleArticle" sender:indexPath];
}
I have to note that PeopleDetailsController is a modal view and PeopleController is a navigation view controller.
EDIT:
The text on the UILabel on the 2nd VC is just not being updated, it stays the same, that's the whole problem.
Change the following
PeopleDetailsController *mdvc = segue.destinationViewController;
mdvc.personsName.text = [self.tablePeople objectAtIndex: indexPath.row];
to
PeopleDetailsController *mdvc = segue.destinationViewController;
mdvc.personsNameString = [self.tablePeople objectAtIndex: indexPath.row];
where personsNameString is a property of type NSString in the PeopleDetailsController
Now in PeopleDetailsController viewDidLoad or viewWillAppear Function set the value of the label to the value of the property
mdvc.personsName.text = personsNameString;