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;
Related
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*/
}
}
i want to pass the properties of data after select a tableviewcell.Please guide me.i already setup the detailviewcontroller.DataArray is my mutablearray in detailviewcontroller.peripheralManager is my NSbject.Peripheral is my device.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
peripheralManager=[[PeripheralManager alloc]init];
self.MeBle.enabled=NO;
device=[[NSMutableArray alloc]init];
}
- (void)peripheralManagerDidConnectPeripheral:(PeripheralManager *)peripheral
{
NSLog(#"%#",peripheral.deviceName);
[device addObject:[NSString stringWithFormat:#" %# ",peripheral.deviceName]];
// [device addObject:peripheral];
[self.deviceTable reloadData];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier=#"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if(cell==nil)
{
cell =[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
cell.textLabel.text=[device objectAtIndex:indexPath.row];
return cell;
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//DetailViewController *detail=[self.storyboard instantiateViewControllerWithIdentifier:#"DetailViewController"];
// [self.navigationController pushViewController:detail animated:YES];
//[self performSegueWithIdentifier:#"TableDetails" sender:[device objectAtIndex:indexPath.row]];
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"TableDetails"]) {
DetailViewController *detail=segue.destinationViewController;
detail.dataArray=device;
}
}
in the prepareForSegue you should get the current selection index:
NSIndexPath *indexPath = [self.deviceTable indexPathForCell:sender];
now, you may either pass just this index to the destination controller OR specific object from you current array, its up to you.
detail.idx = [indexPath row];
Edit: there you don't need to implement
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
just in
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
change to this:
detailViewObject.objCurrentDevice=[device objectAtIndex:[[self.deviceTable indexPathForCell:sender] row]];
In interface builder, check out the seague runtime attributes section, u can create multiple cell same style but different identifier then cellForRowAtIndexPath return the cell by its row
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"];
}
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
I'm trying to update a UITextView's text property, after a segue, which happens after a row of a table view is tapped.
here is my code
MasterViewController.m
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([[segue identifier] isEqualToString:#"4 Choices"]) {
NSLog(#"prepareForSegue is called");
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSManagedObject *selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath];
NSString *questionContent = [[selectedObject valueForKey:#"questionContent"]description];
self.questionContent = questionContent;
[segue.destinationViewController setTextViewWith:self.questionContent];
}
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"didSelectRowAtIndexPath is called");
NSManagedObject *selectedObject = [[self fetchedResultsController] objectAtIndexPath:indexPath];
NSNumber *questionID = [selectedObject valueForKey:#"qID"];
int i = [questionID intValue];
if (i == 1) {
[self performSegueWithIdentifier:#"4 Choices" sender:self];
}
else
{
[self performSegueWithIdentifier:#"5 Choices" sender:self];
}
}
DetailViewController.m
-(void)setTextViewWith:(NSString *)aText
{
self.questionText = aText;
NSLog(#"setTextViewWith is called");
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.questionView setText:self.questionText];
NSLog(#"viewWillAppear is called");
}
EDIT 1 : change the code to set the text at 'viewWillAppear'
EDIT 2 : add 'didSelectRowAtIndexPath'
Note : the segue was pointed from MasterViewController to DetailViewController (not from the
tableViewCell)
Thanks for your help : )
The text view may not be loaded at the prepareForSegue point. I've only just started with storyboards and have found that I had to set string properties on the destination view controller instead, then update the UI components in viewDidLoad or viewWillAppear.