How do I include section information in indexPathForSelectedRow - xcode

I have a table with sections, populated by an array which is comprised of four arrays. How do I modify the indexPathForSelectedRow statements in the prepare for segue method to include section information?
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier]isEqualToString:#"plantSaveSegue"])
{
NSIndexPath *selectedRowIndex = [self.tableView indexPathForSelectedRow];
DetailViewController *grassType = [segue destinationViewController];
//grassType.selectedPlant = [grassArray objectAtIndex:selectedRowIndex.row];
grassType.selectedPlant = [plantArray objectAtIndex:selectedRowIndex.row];
}
}
This works perfectly for one section, but what do I do for four sections?

Declare 2 NSIntegers in the .h file
NSInteger selectedSection;
NSInteger selectedRow;
and now in your viewDidLoad(), initialize these to "-1"
selectedSection = -1;
selectedRow = -1;
Now in
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
selectedSection = indexPath.section;
selectedRow = indexPath.row;
//Now performSegue here
}
After that
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier]isEqualToString:#"plantSaveSegue"])
{
NSIndexPath *selectedRowIndex = [self.tableView indexPathForSelectedRow];
DetailViewController *grassType = [segue destinationViewController];
if(selectedSection == 0){
grassType.selectedPlant = [firstArray objectAtIndex:selectedRow];}
else if(selectedSection == 1){
grassType.selectedPlant = [secondArray objectAtIndex:selectedRow];}
else if(selectedSection == 2){
grassType.selectedPlant = [thirdArray objectAtIndex:selectedRow];}
else if(selectedSection == 3{
grassType.selectedPlant = [fourthArray objectAtIndex:selectedRow];}
}
}
Hope This Helps

Thanks for all the help and guidance. The answer was distressingly simple, type in the complete and correct path for the appropriate item in the table. See below:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([[segue identifier]isEqualToString:#"plantSaveSegue"])
{
NSIndexPath *selectedRowIndex = [self.tableView indexPathForSelectedRow];
DetailViewController *grassType = [segue destinationViewController];
grassType.selectedPlant = [[plantArray objectAtIndex:selectedRowIndex.section]objectAtIndex:selectedRowIndex.row];
}
}

Related

Passing Detail from tableview Controller

I am trying to push my detail view I am using a PFQueryTableView and I persume it was just same as normal so I was using this.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Check that a new transition has been requested to the DetailViewController and prepares for it
if ([segue.identifier isEqualToString:#"destinationViewController"]){
// Capture the object (e.g. exam) the user has selected from the list
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
PFObject *object = [self.objects objectAtIndex:indexPath.row];
dettailViewController *controller = (dettailViewController *) segue.destinationViewController;
controller.clinics = object;
}
}
But it bombs out at the *controller line I have a navigation controller on my storyboard.
When I say it bombs out it complains here
PFObject *object = [self.objects objectAtIndex:indexPath.row];
vc.clinics = object;
and saids thread error
If you are using a nav controller you need to specify the navigation controller in your segue like so:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"ShowDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
PFObject *object = [self.objects objectAtIndex:indexPath.row];
UINavigationController *nav = [segue destinationViewController];
EventDetail *detailViewController = (EventDetail *) nav.topViewController;
detailViewController.event = object;
}
}

IOS 7 Xcode Search Bar Controller Implementation

Sunny Thank you for your reply. I made the following changes and now by clicking on a tablecell or search result, I am pushed to DetailViewController but, for any cell I click on I get the same DetailView. I need the detail view to show different information depending on the cell I click on.
I added this:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView == self.searchDisplayController.searchResultsTableView) {
[self performSegueWithIdentifier: #"ShowDetails" sender: self];
}
}
New segue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"ShowDetails"]) {
DetailViewController *detailviewcontroller = [segue destinationViewController];
NSIndexPath *myIndexPath = [self.tableView indexPathForSelectedRow];
int row = [myIndexPath row];
detailviewcontroller.DetailModal = #[_Title[row],_Attribute[row]];
}
}
update:
The reason I am having difficulty in implementing your code is because my information to be passed to the detailview is in DetailViewController.h but as an array not a string:
#property (nonatomic,strong) NSArray *Title;
#property (nonatomic,strong) NSArray *Attribute;
in the viewdidload I get these from my plist:
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
_Title = [dict objectForKey:#"caseName"];
_Attribute= [dict objectForKey:#"attribute"];
the table view is populated with said data with the following:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"TableViewCell";
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[TableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
if (tableView == self.searchDisplayController.searchResultsTableView)
{
cell.textLabel.text = [self.searchResult objectAtIndex:indexPath.row];
}
else
{
cell.TitleLabel.text = self.Title[indexPath.row];
cell.AttributeLabel.text = self.Attribute[indexPath.row];
}
return cell;
}
Then in the DetailViewController.h:
#property (strong, nonatomic) IBOutlet UILabel *TitleLabel;
#property (nonatomic,strong) IBOutlet UILabel *AttributeLabel;
#property (nonatomic,strong) NSArray *DetailModal;
DetailViewController.m:
_TitleLabel.text = _DetailModal[0];
_AttributeLabel.text = _DetailModal[1];
My segue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"ShowDetails"]) {
DetailViewController *detailviewcontroller = [segue destinationViewController];
NSIndexPath *myIndexPath = [self.tableView indexPathForSelectedRow];
int row = [myIndexPath row];
detailviewcontroller.DetailModal = #[_Title[row],_Attribute[row]];
}
}
I thought it would help to put more of my code so you're able to get clearer picture. In my non expert opinion, I think the reason your code doesn't work for me is because my data is being stored in an array (DetailModal) and not in a string.
Thank you for taking the time to help me with this
You should implement TableView delegate;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (tableView == self.searchDisplayController.searchResultsTableView) {
[self performSegueWithIdentifier:kSHOW_DETAILS sender:cell];
}
else {
[self performSegueWithIdentifier:kSHOW_DETAILS sender:cell];
}
}
Update:
You have to set the value to be displayed in the detailed view. You might declare a property in the header file for your detailView which you might set in prepareForSegue (or in the didSelectRowAtIndexPath above). For example, in DetailViewController you might do this:
#interface DetailViewController: UIViewController
#property (weak, nonatomic) NSString *myDetailValue;
#end
Then in tableView: didSelectRowAtIndexPath: above, set the correct value before you do the segue:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (tableView == self.searchDisplayController.searchResultsTableView) {
// TODO select value from filteredList to set the detailViewController, e.g.:
self.detailedViewController.myDetailValue = valueFromFilteredListForIndexPath;
[self performSegueWithIdentifier:kSHOW_DETAILS sender:cell];
}
else {
// TODO select value from regular list to set the detailViewController, e.g.:
self.detailedViewController.myDetailValue = valueFromRegularListForIndexPath;
[self performSegueWithIdentifier:kSHOW_DETAILS sender:cell];
}
}
Similarly, you can do it the prepare for segue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([[segue identifier] isEqualToString:#"ShowDetails"]) {
DetailViewController *detailviewcontroller = [segue destinationViewController];
NSIndexPath *myIndexPath;
if (self.inSearch) {
myIndexPath = [self.searchDisplayController.searchResultsTableView indexPathForSelectedRow];
detailedViewController.myDetailValue = valueFromFilteredListForIndexPath;
}
else {
myIndexPath = [self.tableView indexPathForSelectedRow];
detailedViewController.myDetailValue = valueFromRegularListForIndexPath;
}
}
}

Link a search bar cell label to view controller

I am trying to create a search bar in Xcode so when you search for an item, you can click on the search result cell and it will go to a view controller but all it is doing now is going to the sea view controller and just displaying the label of the cell i clicked on.
Here is my .m file
#interface ListTableViewController () <UISearchDisplayDelegate>
#property (strong, nonatomic) NSArray *dataArray;
#property (strong, nonatomic) NSArray *searchResults;
#end
#implementation ListTableViewController
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.dataArray = [NSArray arrayWithObjects:#"Tomb Raider", #"Little Big Planet", #"Unchanted 3", #"BlackOps 2", nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)filterContentForSearchText: (NSString *) searchText
{
NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:#"SELF CONTAINS[cd] %#", searchText];
self.searchResults = [self.dataArray filteredArrayUsingPredicate:resultPredicate];
}
-(BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self filterContentForSearchText:searchString];
return YES;
}
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section
{
if (tableView == self.tableView) {
return [self.dataArray count];
} else { // (tableView == self.searchDisplayController.searchResultsTableView)
return [self.searchResults count];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (tableView == self.tableView) {
cell.textLabel.text = [self.dataArray objectAtIndex:indexPath.row];
} else {
cell.textLabel.text = [self.searchResults objectAtIndex:indexPath.row];
}
return cell;
}
#pragma mark - Table view delegate
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"showDetails"]) {
DetailsViewController *dvc = segue.destinationViewController;
NSIndexPath *indexPath = nil;
if ([self.searchDisplayController isActive]) {
indexPath = [self.searchDisplayController.searchResultsTableView indexPathForSelectedRow];
dvc.sendLabel = [self.searchResults objectAtIndex:indexPath.row];
return;
} else{
indexPath = [self.tableView indexPathForSelectedRow];
dvc.sendLabel = [self.dataArray objectAtIndex:indexPath.row];
return;
}
}
}
#end
Thanks, anything will help.
You must implement this delegate method :
// Method returns the clicked row.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
YourPushedViewController *ypVC = [[YourPushedViewController alloc] initWithNibName:#"YourPushedViewController" bundle:nil];
ypVC.selectedText = myResultArray[indexPath.row];
[self.navigationController pushViewController:ypVC animated:YES];
}
That method is response for selecting row and passing selected result to another view.
This is hint for you :Passing Data between View Controllers

Button to Select Random Cell in tableView

How could I create a button on the Table View that when touched randomly selects one of the cells?
I know how to add Round Rect Button and all, just not the code part of selecting a random cell.
Thanks!
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"showRecipeDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
RecipeDetailViewController *destViewController = segue.destinationViewController;
destViewController.recipe = [recipes objectAtIndex:indexPath.row];
// Hide bottom tab bar in the detail view
// destViewController.hidesBottomBarWhenPushed = YES;
}
Hello as you have mentioned in your comment that you have only one section with 36 cells. find the rendom row using arc4random.
Then fetch your indexPath from section and row.
then call didSelectRowAtIndexPath
Whole code of your button click method will look like....
int section = 0;
int row = arc4random() %35;
NSIndexPath * path = [NSIndexPath indexPathForRow:row inSection:section];
if ([self.yourTableView.delegate respondsToSelector:#selector(tableView:willSelectRowAtIndexPath:)]) {
[self.yourTableView.delegate tableView:self.yourTableView willSelectRowAtIndexPath:path];
}
[self.yourTableView selectRowAtIndexPath:path animated:YES scrollPosition: UITableViewScrollPositionNone];
if ([self.yourTableView.delegate respondsToSelector:#selector(tableView:didSelectRowAtIndexPath:)]) {
[self.yourTableView.delegate tableView:self.yourTableView didSelectRowAtIndexPath:path];
}
Then implement didSelectRowAtIndexPath
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UIButton * btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.tag = indexPath.row;
[self performSegueWithIdentifier:#"showRecipeDetail" sender:btn];
}
Make sure that you have written following code in viewDidLoad
self.yourTableView.delegate = self;
self.yourTableView.dataSource = self;
And change prepareForSegue method as below
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"showRecipeDetail"]) {
RecipeDetailViewController *destViewController = [segue destinationViewController];
NSInteger tagIndex = [(UIButton *)sender tag];
destViewController.recipe = [recipes objectAtIndex:tagIndex];
}
}
This will surely help you.....

Repeat issue with UITableView cells

I am fully aware there are many cases of this issue here, although I am stumped and cannot resolve this on my own. I only want to display 4 cells total in my myTableView2 UITableView, but what I am finding is that my cells are being reused no doubt because of this line
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
I understand if I remove the if(!cell) line I might disable the UITableView from creating new cells, but that doesn't work because it mandates cell creation. Any thoughts? I have posted my code below.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
{
NSLog(#"CREATING NEW CELL");
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
cell.contentView.autoresizesSubviews = YES;
cell.contentView.clipsToBounds = YES;
}
if (tableView == self.myTableView)
{
if ([[array objectAtIndex:indexPath.row] isKindOfClass:[NSNumber class]])
{
cell.textLabel.text = [[array objectAtIndex:indexPath.row] stringValue];
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.textAlignment = NSTextAlignmentCenter;
}
else
{
cell.textLabel.text = [array objectAtIndex:indexPath.row];
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.textAlignment = NSTextAlignmentCenter;
}
}
if (tableView == self.myTableView2)
{
self.myTableView2.opaque = NO;
self.myTableView2.backgroundColor = [UIColor colorWithRed:(0.0/255.0) green:(0.0/255.0) blue:(102.0/255.0) alpha:1.0];
self.myTableView2.backgroundView = nil;
if ([[array2 objectAtIndex:indexPath.row] isKindOfClass:[NSNumber class]])
{
cell.textLabel.text = [[array2 objectAtIndex:indexPath.row] stringValue];
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
cell.textLabel.textAlignment = NSTextAlignmentCenter;
cell.textLabel.numberOfLines = 0;
[cell.textLabel sizeToFit];
cell.textLabel.font = [self fontForCell];
}
else
{
cell.textLabel.text = [array2 objectAtIndex:indexPath.row];
cell.textLabel.textColor = [UIColor whiteColor];
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
cell.textLabel.textAlignment = NSTextAlignmentCenter;
cell.textLabel.numberOfLines = 0;
[cell.textLabel sizeToFit];
cell.textLabel.font = [self fontForCell];
}
}
return cell;
}
Other pertinent data:
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (tableView==self.myTableView)
{
return [array count];
}
else if(tableView==self.myTableView2)
{
return [array2 count];
}
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView==self.myTableView)
{
return [array count];
}
else if(tableView==self.myTableView2)
{
return [array2 count];
}
}
Solved!
Problem #1: the NSDictionary "for" loop was unnecessary and was contributing to multiple entries. I erased the loop.
Problem #2: numberOfSectionsInTableView and numberOfRowsInSection. Edited version below. Lesson learned: you want numberOfSectionsInTableView to reflect 1 if you only want one instance of your array shown. A value of 2 will cause two instances to be shown, so on and so forth.
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (tableView==self.myTableView)
{
return [array count];
}
else if(tableView==self.myTableView2)
{
return 1;
}
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView==self.myTableView)
{
return 5;
}
else if(tableView==self.myTableView2)
{
return [array2 count];
}
}

Resources