The code for Tableview :
-(void)tableView:(UITableView *)tableView didselectRowAtIndexPath:(NSIndexPath *)indexPath{
ViewControllerDisplayMsg *detail = [self.storyboard instantiateViewControllerWithIdentifier:#"viewController3"];
cellvalue=[array objectAtIndex:indexPath.row];
detail.DisplayMsgString = cellvalue;
[self.navigationController pushViewController:detail animated:YES];
}
Code in viewController3 :
- (void)viewDidLoad
{
[super viewDidLoad];
self.DisplayMsgLabel.text= self.DisplayMsgString;
}
The code above is not passing data its blank when the viewcontroller3 is opened.Why is the data not passing .What code is missing ?
Please help me out.Really appreciate the help.
Thanks in Advance.
You have used
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath{
}
It is
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
}
I hope you have typed it by mistake please share your result if it is something else than this
Since I had segue from the story board The didselect method was not being called so -
(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// test segue.identifier if needed
ViewControllerDisplayMsg *viewController = segue.destinationViewController;
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
// set properties of viewController based on selection indexPath
cellvalue=[array objectAtIndex:indexPath.row];
NSLog(#"str : %#",cellvalue);
viewController.DisplayMsgtext = cellvalue;
}
This worked perfectly fine.I have to check it if this is right way of implementing but otherwise its working fine now.
Related
I'm trying to pass data (array) with PrepareForSegue into a detailed VC. The destination VC has a label that receives a string. I thought I could transform the array into a string, and the rest was straightforward. This was achieved, though, but kind of wrongly, because, obviously, the text I get, regardless the row I click, returns me the whole object...And my goal is to get details of a specific row...Can someone help me? Guess this is basic stuff, but this is my first app...The method PrepareForSegue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"detail"]) {
NSString *places = [_spots componentsJoinedByString:#" "];
DetailViewController * destination = segue.destinationViewController;
destination.detailedText = places;
}
EDIT:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
NSManagedObject *ls = [self.spots objectAtIndex:indexPath.row];
NSLog(#"Table Spots are: %#", ls);
[cell.textLabel setText:[NSString stringWithFormat:#"%#", [ls valueForKey:#"name"]]];
cell.imageView.image = [UIImage imageNamed:#"city.jpg"];
return cell;
}
As far as I understood, you want to performSegue() on a row selection and you want to pass a data specific to the selected row. In order to do this you can use the tableView.indexPathForSelectedRows() method, which is going to return an array with the indexPaths of all selected rows. Then you can get the UITableViewCells for this indexPaths and get their data.
You can pass the string value to the perforSegue method as the sender:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self performSegueWithIdentifier:#"detail" sender:[_spots objectAtIndex:indexPath.row]];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"detail"]) {
DetailViewController * destination = segue.destinationViewController;
destination.detailedText = sender;
}
}
I am newbie to iOS and learning things in iOS. I am making a demo of UITableView and Segue. I have successfully implemented table-view and now I want to pass the value to another View Controller using segue. I have tried as below, but my problem is I am getting same record every time on detail button clicked from UITableView. I don't have any idea what is wrong in my code.
Can anybody help me to figure it out?
I am posting my code here:
code
-(void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath{
//NSDictionary *dict = [myArray objectAtIndex:indexPath.row];
// NSString *name = [dict valueForKey:#"name"];
[self performSegueWithIdentifier:#"detail" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"detail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
//NSLog(#"selected index path==%#",indexPath);
DetailView *destViewController = segue.destinationViewController;
destViewController.details = [myArray objectAtIndex:indexPath.row];
}
}
Change your code as below, you don't need to send self as the sender. Send indexPath
-(void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath{
[self performSegueWithIdentifier:#"detail" sender:indexPath];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"detail"]) {
NSIndexPath *indexPath = sender;
DetailView *destViewController = segue.destinationViewController;
destViewController.details = [myArray objectAtIndex:indexPath.row];
}
}
I can't seem to find how to display another 'UIViewController' view when one row is clicked. So like when the row is clicked it goes to the next view and displays more information about row.
I think I need to use something like the - (void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath delegate. Then my second question is how do I pass the data that was in that row, like the title, to the next view controller?
Thanks
If you are using a storyboard:
.h
#interface YourTableViewController : UIViewController
{
// you just need int selectedRow inside of #interface
int selectedRow;
}
.m
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// this method is going to give you NSIndexPath *indexPath
selectedRow = indexPath;
[self performSegueWithIdentifier:#"nameOfYourSegue" sender:self];
}
You might already have this method, add the code inside of it if that's the case. This method is called when a segue is about to perform.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([[segue identifier] isEqualToString:#"nameOfYourSegue"]){
//Pass data from one controller to the next
[[segue destinationViewController] setRowIndex:selectedRow];
}
}
selectedRow is going to have the index of which row was selected with 0 being the first row.
In your next view controller's class:
.h
- (void)setRowIndex:(int)rowIndex;
.m
- (void)setRowIndex:(int)rowIndex
{
//assign your variable to rowIndex
}
Once you have this working, you can edit this code to pass an array of information.
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
NSString *title = cell.textLabel.text;
Like #rmaddy said, Its better if you do some research, This is very basic, I would recommend you the:
http://www.raywenderlich.com/
Site for great tutorial, they really have every thing you need there.
Here is a hypothetical example:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
MyCustomViewController *vc = [[MyCustomViewController alloc]initWithTitle:selectedCell.textLabel.text];
// Assuming your UITableViewDelegate has a navigationController
[self.navigationController presentViewController:vc animated:YES completion:nil];
}
use the method:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
you can get the cell by the index path:
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
the code:
- (void)tableView:(UITableView *)tblView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
}
after getting the cell data youc can use it
answer to question 2:
you can connect in the interface builder your cell with the next vc by seque and in the method prepareforseque just pass the data to the
segue.destenationViewController.yourPoperty
now in the viewdidload method:
self.title = self.property
Currently I just have a segue hooked up to a UITableView that pops to the next UITableView in the navigation stack.
What I need to do though now instead, is set up an if statement based on the text in the UITableView cell, to decide which of two possible UIViewControllers to pop to.
So ViewController2 needs to be able to pop either":
- back to ViewController1
OR
- forward to ViewController3
based on the text in the UITableView cell that is populated by JSON.
Can you help me out with that? Will post any code needed. Thanks!
Current ViewController:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"standardCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Spring *spring = [springs objectAtIndex:indexPath.section];
Leaf *leaf = [spring.leafs objectAtIndex:indexPath.row];
cell.textLabel.text = leaf.shortName;
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
if ([segue.identifier isEqualToString:#"themes"]) {
UITableViewCell *cell = (UITableViewCell*)sender;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
// Get reference to destination view controller
MRTViewController *tvc = (MRTViewController *)[segue destinationViewController];
}
}
UPDATE
Added code per #troops but still not sure how to pop to VC3
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *stringToCheck = #"AAA";
if([cell.textLabel.text isEqualToString:stringToCheck])
{
//Pop to VC1
[self.navigationController popToViewController:[[self.navigationController viewControllers]objectAtIndex:0] animated:YES];
} else {
//Pop to VC3, not sure what to put here
// Pass the info
tvc.spring = [springs objectAtIndex:indexPath.section];
tvc.leaf = [tvc.spring.leafs objectAtIndex:indexPath.row];
tvc.buttonNumber = _buttonNumber;
}
}
You could simply check the cell's textLabel's string: If you really want to use segues and not the tableView's delegate method of: didSelectRowAtIndexPath: That's why I based my answer off what your initial question/code looks like.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSString *stringToCheck = #"AAA";
if ([cell.textLabel.text isEqualToString:stringToCheck])
{
// Pop to VC1
[self.navigationController popToRootViewControllerAnimated:YES];
}
else
{
// Push to VC3
MRTViewController3 *tvc = [self.storyboard instantiateViewControllerWithIdentifier:#"YourID"];
tvc.spring = [springs objectAtIndex:indexPath.section];
tvc.leaf = [tvc.spring.leafs objectAtIndex:indexPath.row];
tvc.buttonNumber = _buttonNumber;
[self.navigationController pushViewController:tvc animated:YES];
}
}
Use delegate method, get cell, compare text.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if([cell.textLabel.text isEqualToString:#"Your String"])
{
//Pop or present view controller
}
}
I have a universal application that is very basic. It is a master detail. When I segue from the master to the detail, I set the text in a label, and set the title of the destination view controller with an NSString. This works fine on iPhone, but on iPad, it doesn't set the title or the label. Here is the code I am using to set everything:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSString *object = dailyGramsNumbers[indexPath.row];
NSString *object1 = dailyGramsBody [indexPath.row];
[[segue destinationViewController] setDetailItem:object1];
[[segue destinationViewController] setTitle:object];
}
}
thanks for any help!
here is the code I am using now (in addition to the above code):
- (void)tableView:
(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
NSString *object = dailyGramsNumbers[indexPath.row];
[self.splitViewController.viewControllers[1] setTitle:object];
self.detailViewController.detailItem = object;
}
}
A split view controller has a viewControllers property, and the controller at index 1 will be the detail controller. So, you can accomplish the same task on the iPad version by putting in this code,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *object = dailyGramsNumbers[indexPath.row];
NSString *object1 = dailyGramsBody[indexPath.row];
[self.splitViewController.viewControllers[1] setDetailItem:object1];
[self.splitViewController.viewControllers[1] setTitle:object];
}
You should import the DetailController.h file into the .m file of the master controller, and you might have to cast self.splitViewController.viewcontrollers[1] to your detail controller class.
After Edit:
If the detail controller is embedded in a navigation controller, code like this should work,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *object = dailyGramsNumbers[indexPath.row];
NSString *object1 = dailyGramsBody[indexPath.row];
[(DetailViewController *)[self.splitViewController.viewControllers[1] topViewController] setDetailItem:object1];
[(DetailViewController *)[self.splitViewController.viewControllers[1] topViewController] setTitle:object];
}