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
}
}
Related
When a table view is pressed, I am trying to grab the value of a textview from that table view row that has been selected as follows.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
{
tabBar = [self.storyboard instantiateViewControllerWithIdentifier:#"TabBarController"];
[self.navigationController pushViewController:tabBar animated:YES];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
MyOrdersController *detailVC = [[MyOrdersController alloc]init];
NSLog(#"hello %#", detailVC.shipmentReferenceNumberTextLabel.text);
}
But im getting null value. How can I get the value of the textview in that specific row?
You can grab the textview from selected cell subview.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
{
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
for (id txtView in selectedCell.subviews)
{
if ([txtView isKindOfClass:[UITextView class]])
{
UITextView* tv = (UITextView*)txtView;
NSString* text = tv.text;
}
}
}
Just try it:-
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
NSString *cellText = selectedCell.textLabel.text;
}
I have a Master-Detail tableview and would like take the user to a different Detail VC depending on properties of the object being displayed.
For example, if an actor is in a movie, I'd like to go to a movie View Controller, but if the actor is in a TV show, a view controller optimized for a TV show.
I have wired the detail VCs to the view controller, not the table view so that using didSelectRowAtIndexPath, I can send the user to different detail VCs using logic and performSegue.
However, the information needed to implement the logic is in the data object in cellforrowatindexpath. So my question is how can pass this info to didSelectRow or alternatively place the logic for the segue in cellforrowatindexpath.
Thanks for any suggestions.
Here is my current code:
- (void)tableView: (UITableView *)tableView didSelectRowAtIndexPath: (NSIndexPath *)indexPath {
UITableViewCell *theCellClicked = [self.tableView cellForRowAtIndexPath:indexPath];
NSString *segueName = nil;
if ([_credit.type isEqual: #"movie"]) {
segueName = #"goToMovie";
}
else if ([_credit.type isEqual: #"television"]) {
segueName = #"goToTVShow";
}
[self performSegueWithIdentifier: segueName sender: self];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
Credit *credit = [self.fetchedResultsController objectAtIndexPath:indexPath];
}
cell.textLabel.text = credit.name;
return cell;
}
Your fetched results controller will still be in scope inside didSelectRowAtIndexPath. So you can:
Credit *credit = [self.fetchedResultsController objectAtIndexPath:indexPath];
if ([credit.type isEqual: #"movie"]) {
segueName = #"goToMovie";
}
else if ([credit.type isEqual: #"television"]) {
segueName = #"goToTVShow";
}
I have the following code. I want to display the data that is selected. However, below code is display every post in database. I would like it to display just the one that is selected. How can i do that?
Post Table View Controller:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[super tableView:tableView didSelectRowAtIndexPath:indexPath];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if (![self objectAtIndexPath:indexPath]) {
// Load More Cell
[self loadNextPage];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.objects.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
static NSString *CellIdentifier = #"Cell";
UserFeedTableViewCell *cell = (UserFeedTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UserFeedTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (object) {
cell.postView.text = [object objectForKey:#"post"];
// PFQTVC will take care of asynchronously downloading files, but will only load them when the tableview is not moving. If the data is there, let's load it right away.
}
return cell;
}
Details View Controller:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath object:(PFObject *)object {
static NSString *CellIdentifier = #"Cell1";
CommentsTableViewCell *cell = (CommentsTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[CommentsTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (object) {
cell.detailsPost.text = [object objectForKey:#"post"];
}
return cell;
}
You should select a row in tableView:didSelectRowAtIndexPath
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// store relevant value in your text object
[self performSegueWithIdentifier:#"showSegue" sender:self];
[self.tableView deselectRowAtIndexPath:indexPath animated:NO];
}
and the perform segue
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
DetailViewController *controller= [segue destinationViewController];
// set your text object here
controller.text = // your text object
}
HTH
Create an object of the detail table view controller (on which you have to display the data) in the table view controller (from which data is sent), in the following way,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
DetailTableViewController *objNext = (DetailTableViewController *)[self.storyboard instantiateViewControllerWithIdentifier:#"detailVC"];
objNext.strLink=[[feeds objectAtIndex:indexPath.row] valueForKey:#"link"];
[self.navigationController pushViewController:objNext animated:YES];
}
Pass the data which you want to pass on row select,
Here are some links which show how to pass data from one view controller to another, some of them are from stack overflow itself.
Passing Data between View Controllers
ios Pass data between navigation controller
https://teamtreehouse.com/community/how-to-pass-data-between-two-view-controllers-when-you-have-tab-bar-and-navigation-controller-in-between
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
So what I am trying to do is I have an NSMutableArray of data I need to pass to another UITableViewController. This NSMutableArray is an array of NSDictionaries that contain the information I want to be displayed in the title of each table view cell. Here is my code before I segue.
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSIndexPath* indexPath = [self.tableView indexPathForCell:sender];
if ([segue.identifier isEqualToString:#"Title Query"]) {
UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:indexPath];
NSString* cellText = cell.textLabel.text;
NSMutableArray* photosToBeShown = [self titleQuery:cellText];
if ([segue.destinationViewController respondsToSelector:#selector(setPhotoTitles:)]) {
[segue.destinationViewController performSelector:#selector(setPhotoTitles:) withObject: photosToBeShown];
NSLog(#"%#", photosToBeShown);
}
}
}
The method setPhotoTitles: that is called by the performSelector: withObject: is the setter of the property (NSMutableArray* ) photoTitles on the UITableViewController that I am seguing to because I wanted to collect the array so I could then call the methods below to set the titles of my table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Photo Title Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
cell.textLabel.text = [self titleForRow:indexPath.row];
return cell;
}
- (NSString *) titleForRow: (NSUInteger) row
{
return self.photoTitles[row];
}
What happens when I run this code is I end up in an infinite loop with calls to my setter method (setPhotoTitles:). Now my question is what is the right conceptual way to get around this problem or how can I implement it this way without ending up in an infinite loop. I have all the information I need in my array but I need to pass the array to the new controller but also be able to use the UITableViewCell method to set the rows titles.
In the prepareForSegue: method, rather than overriding setPhotoTitles:, you should create a NSArray property in the destination view controller, as pass the photoTitles array to the NSArray property of the destination view controller. So your prepareForSegue method would look like this:
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSIndexPath* indexPath = [self.tableView indexPathForCell:sender];
if ([segue.identifier isEqualToString:#"Title Query"]) {
UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:indexPath];
NSString* cellText = cell.textLabel.text;
NSMutableArray* photosToBeShown = [self titleQuery:cellText];
YourCustomViewController *customViewController = segue.destinationViewController;
customViewController.photosArrayProperty = photosToBeShown;
}
}