I am trying to pass data from one table view Cell to next UIViewController . I am using Navigation Controller also , But when i am clicking Cell then it giving error :-
-[UIViewController setSelectedRowTitle:]: unrecognized selector sent to instance 0x13fab360
my prepareForSegue code which i used go next with data is:-
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [NearBy_PlacesArray count];
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *TableIdentifire = #"NearMe";
NearByTableViewCell *cell = (NearByTableViewCell*)[self.tableView dequeueReusableCellWithIdentifier:TableIdentifire];
if (cell == nil)
{
cell = [[NearByTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TableIdentifire];
}
NearByPlace *nearBy = [NearBy_PlacesArray objectAtIndex:indexPath.row];
cell.NearBy_Thumbnail_Image.image = [UIImage imageNamed:nearBy.NearByImageName];
cell.NearBy_TitleLabel.text = nearBy.NearByPlaceName;
cell.NearBy_NoLabel.text = nearBy.NearByPlace_no;
return cell;
}
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"ShowNearByPlaces"])
{
NSIndexPath *indexPath = nil;
NearByPlace *nearPlace = nil;
indexPath = [self.tableView indexPathForSelectedRow];
nearPlace = [NearBy_PlacesArray objectAtIndex:indexPath.row];
NSLog(#"indexPath-- %# \n" , indexPath);
NSLog(#"recipe-- %# \n " , nearPlace);
nearByPlaceDetail_ViewController *destViewController = segue.destinationViewController;
destViewController.SelectedRowTitle = nearPlace;
}
}
Mantosh, you can simply do this :
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *aStrIdentifier = #"cell";
UITableViewCell *aCell=[tableView dequeueReusableCellWithIdentifier:aStrIdentifier];
UILabel *aLblPlaceName=(UILabel*)[aCell viewWithTag:1];
aLblPlaceName.text=[NSString stringWithFormat:#"%#", [arrPlaces objectAtIndex:indexPath.row]];
return aCell;
}
(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
strStoreValue = [NSString stringWithFormat:#"%#", [arrPlaces objectAtIndex:indexPath.row]];
[self performSegueWithIdentifier:#"detailViewSegue" sender:self];
}
(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
DetailViewController *aObjDetailVC = segue.destinationViewController;
aObjDetailVC.strPlace = strStoreValue;
}
Related
I'm using two different custom table cells in my table view. That said, I only want didSelectRowAtIndexPath to fire when, for example, Custom Cell Identifier 2 is tapped (but not when Custom Cell Identifer 1 is tapped). How might I go about this? See code below. Right now, didSelectRowAtIndexPath fires when either cell is tapped...
- (void)viewDidLoad {
[super viewDidLoad];
static NSString *ChatTableIdentifier = #"ChatTableViewCell";
static NSString *ChatTableIdentifier2 = #"SwapDetailTableViewCell";
UINib *nib = [UINib nibWithNibName: ChatTableIdentifier bundle:nil];
[self.tableView registerNib:nib forCellReuseIdentifier: ChatTableIdentifier];
UINib *nib2 = [UINib nibWithNibName: ChatTableIdentifier2 bundle:nil];
[self.tableView registerNib:nib2 forCellReuseIdentifier: ChatTableIdentifier2];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *data = self.messages[indexPath.row];
id swaptime = data[#"swaptime"];
if ([swaptime isKindOfClass:[NSString class]]) {
static NSString *ChatTableIdentifier2 = #"SwapDetailTableViewCell";
SwapDetailTableViewCell *cell = (SwapDetailTableViewCell *)[tableView dequeueReusableCellWithIdentifier:ChatTableIdentifier2 forIndexPath:indexPath];
NSString *time = data[#"swaptime"];
cell.startTime.text = time;
NSString *timeEnd = data[#"endswaptime"];
cell.endTime.text = timeEnd;
return cell;
} else {
static NSString *ChatTableIdentifier = #"ChatTableViewCell";
ChatTableViewCell *cell = (ChatTableViewCell *)[tableView dequeueReusableCellWithIdentifier:ChatTableIdentifier forIndexPath:indexPath];
NSString *userName = data[#"name"];
cell.sendingUser.text = userName;
NSString *messageBody = data[#"body"];
cell.messageDisplayed.text = messageBody;
NSString *timeReceived = data[#"published at"];
cell.timeStamp.text = timeReceived;
return cell;
}
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
SwapDetailsViewController *detailViewController = [[SwapDetailsViewController alloc]
initWithNibName:#"SwapDetailsViewController" bundle:nil];
detailViewController.swapDetails = [self.messages objectAtIndex:indexPath.row];
[self presentViewController:detailViewController animated:YES completion:nil];
}
You can put an if condition inside didSelectRowAtIndexPath as the one you put in cellForRowAtIndexPath
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *data = self.messages[indexPath.row];
id swaptime = data[#"swaptime"];
//perform action based on this, and don't do anything in second case
if ([swaptime isKindOfClass:[NSString class]])
//this indexPath will always contain cell of one kind
}else{
// this indexPath will contain second cell kind
}
}
Or alternatively you can also do-
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// this will give you cell at the selected indexPath
id cell = [tableView cellForRowAtIndexPath:indexPath]
//perform action based on this, and don't do anything in second case
if ([cell isKindOfClass:[SwapDetailTableViewCell class]])
}else{
}
}
If you don't want a particular row to be selected, the proper solution is to implement the tableView:willSelectRowAtIndexPath: delegate method and return nil for rows you don't want selected.
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (some condition) {
return nil;
} else {
return indexPath;
}
}
So now you need to determine the proper condition. I can think of three ways in your case:
Use the same if condition you have in cellForRowAtIndexPath:.
Get the row's cell and look at the cell's class.
Get the row's cell and look at the cell's reuse identifier.
Option 1 isn't ideal because if you change the logic in cellForRowAtIndexPath you have to remember to change it here too. Options 2 and 3 are essentially the same in this case. I'd go with option 3.
- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if ([cell.reuseIdentifier isEqualToString: ChatTableIdentifier) {
return nil;
} else {
return indexPath;
}
}
Since you are now using ChatTableIdentifier in three places, I would move the lines:
static NSString *ChatTableIdentifier = #"ChatTableViewCell";
static NSString *ChatTableIdentifier2 = #"SwapDetailTableViewCell";
to before the #implementation line and remove them from everywhere else in the file. No sense in recreating the same variables over and over.
In didSelectRowAtIndexPath you can call method
(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
for the indexPath of a current row and get the cell you are currently selecting. Every cell has a reuse identifier, so you can check the identifier of the cell you are selecting. if it equals "SwapDetailTableViewCell", then you can perform everything you need(for example move to another viewController)
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if ([cell.reuseIdentifier isEqual: #"SwapDetailTableViewCell"]) {
SwapDetailsViewController *detailViewController = [[SwapDetailsViewController alloc]
initWithNibName:#"SwapDetailsViewController" bundle:nil];
detailViewController.swapDetails = [self.messages objectAtIndex:indexPath.row];
[self presentViewController:detailViewController animated:YES completion:nil];
}
I have a custom cell with few views and buttons in it. From 1 of the buttons, I'm performing a Segue and I need that cell number but no idea how to get it. Please help.
Heres how my cell looks:
the prepareForSegue is called from the red circled button.
Here's the code:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return _array.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NewsFeedCell *cell = [tableView dequeueReusableCellWithIdentifier:#"NewsFeedCell" forIndexPath:indexPath];
if (cell) {
cell.item = _array[indexPath.section];
}
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"AudioComment"])
{
NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
NSLog(#"%ld",(long)indexPath.section); //printing 0 everytime :(
}
}
Please provide any help/suggestions on how can i get the indexPath?
Thanks.
You can use
UITableViewCell *cell = (UITableViewCell *)[[sender superview]superview];
NSLog(#"%ld",(long)[_generalTableView indexPathForCell:cell].row);
You have to set tag on the button. In your case, set the button tag as indexPath.section in CellforRowAtIndexPath.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NewsFeedCell *cell = [tableView dequeueReusableCellWithIdentifier:#"NewsFeedCell" forIndexPath:indexPath];
if (cell) {
cell.item = _array[indexPath.section];
}
cell.button1.tag = indexPath.section;
return cell;
}
In PrepareForSegue, get the index from button tag.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"AudioComment"])
{
NSInteger index = ((UIButton *) sender).tag;
NSLog(#" %ld ",index);
}
}
Add a variable for the index and set it when selecting the cell. Access the variable in perpareForSegue, pass it to the destinationVC and 0 it.
Use below code. It may help you.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
MainPhotoCell *cell = (MainPhotoCell *)[tableView dequeueReusableCellWithIdentifier:#"CellIdentifierMedia" forIndexPath:indexPath];
if (!cell)
{
cell = [[MainPhotoCell alloc] init];
}
cell.usrCommentBtn.tag = indexPath.row;
[cell.usrCommentBtn addTarget:self action:#selector(onCommentClick:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
- (void)onCommentClick:(id)sender
{
if ([GlobalManager checkUserLoginStatus:self])
{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:([sender tag]) inSection:0];
[self performSegueWithIdentifier:#"showComments" sender:indexPath];
}
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString: #"showComments"])
{
NSIndexPath * path = (NSIndexPath *)sender;
//do the your required code here.
}
}
i try to use an unwind method to return the value of a row (from a table ) in another view
but the value catch in the first viewController is null.
This is the code in FirstViewController
- (IBAction)retrievePremadeMessage:(UIStoryboardSegue *)segue;(h)
- (IBAction)retrievePremadeMessage:(UIStoryboardSegue *)segue
{
PreStoredMessagesTableViewController *cc = segue.sourceViewController;
self.textViewMsg = [[UITextView alloc] init];
self.textViewMsg.text = cc.valeurCell;
NSLog(#"cell selected: %#", cc.valeurCell);
}
and this is the secondViewController
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Retrieve the value of cell selected
self.valeurCell = [NSString stringWithFormat:#"%#", [tableView cellForRowAtIndexPath:indexPath].textLabel.text];
}
Thank you
In this method:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Retrieve the value of cell selected
self.valeurCell = [NSString stringWithFormat:#"%#", [tableView cellForRowAtIndexPath:indexPath].textLabel.text];
}
Add:
[self performSegueWithIdentifier:#"identifier" sender:[NSString stringWithFormat:#"%#", [tableView cellForRowAtIndexPath:indexPath].textLabel.text]];
and then you can do something like this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
NSString *stringPassedIn = id;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"Abelia"]) {
if ([[segue destinationViewController] isKindOfClass:[SpeciesViewController class]]) {
SpeciesViewController *Species = (SpeciesViewController *)[segue destinationViewController];
Species.SpeciesInt = 0;
}
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection: (NSInteger)section
{
if (SpeciesInt == 0)
return [abeliaArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"SpeciesNameCell";
SpeciesNameCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[SpeciesNameCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"SpeciesNameCell"];
[cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
}
if (SpeciesInt == 0)
cell.SpeciesNameLabel.text = [abeliaArray objectAtIndex:indexPath.row];
return cell;
}
Im not sure where the problem in this 3 methods, it runs but the abeliaArray will run in place of the other arrays when I try to push. I have other arrays but when I push those the objects in the abeliaArray will show instead of the objects for that array.
I'm unable to populate the second UITableView Controller, wondering if anyone could help.
I'm using a websites API, JSON, and RestKit for the data. I believe that part is working fine because my first VC loads fine.
But I'm not sure if I need to use prepareForSegue and/or didSelectRowAtIndexPath so that I can identify the cell/row selected in the first VC, so that the second VC populates with the (correct) data.
1st VC populates correct:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return sports.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
Sport *sport = [sports objectAtIndex:section];
return sport.leagues.count;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
Sport *sport = [sports objectAtIndex:section];
return sport.name;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"standardCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Sport *sport = [sports objectAtIndex:indexPath.section];
League *league = [sport.leagues objectAtIndex:indexPath.row];
cell.textLabel.text = league.name;
return cell;
}
2nd VC populates blank table:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return leagues.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
League *league = [leagues objectAtIndex:section];
return league.teams.count;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
League *league = [leagues objectAtIndex:section];
return league.name;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"standardCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
League *league = [leagues objectAtIndex:indexPath.section];
Team *team = [league.teams objectAtIndex:indexPath.row];
cell.textLabel.text = team.name;
return cell;
}
Or if I try to add extra code for 1st VC, app crashes before getting to 2nd VC:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
TeamsViewController *teamsViewController = [[TeamsViewController alloc] initWithNibName:#"TeamsViewController" bundle:nil];
teamsViewController.title = [[sports objectAtIndex:indexPath.row] objectForKey:#"sports"];
}
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:#"leagueDetail"]) {
TeamsViewController *tvc = [segue destinationViewController];
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
tvc.data = [self.navigationController objectInListAtIndex:indexPath.row]
}
Would really appreciate any help!
I am a little bit confused with excepting of creation UITableViewCell object. When you ask table view for dequeuing cell it returns one which it does not need at the moment, if there are no unused cell you have to create a new one. Try code like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Create cell
NSString *cellIdentifier = #"cell";
UITableViewCell *cell = nil;
cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:cellIdentifier];
cell.selectionStyle = UITableViewCellSelectionStyleGray;
}
cell.textLabel.text = [NSString stringWithFormat:#"cell %d", indexPath.row];
return cell;
}