I created custom UITableView with a button. User open homepage when click the button.
Homepage Address of the buttons are Json parsing. In other words, the homepage address is different for each button.
I don't know how can I setting a different address for each button.
This is my Source Code.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"customCell";
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil){
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
}
[cell.title setText:[[list objectAtIndex:indexPath.row] objectForKey:#"title"]];
[cell.date setText:[[list objectAtIndex:indexPath.row] objectForKey:#"date"]];
NSString *listSite = [[list objectAtIndex:indexPath.row] objectForKey:#"site"];
UIButton *cellButton = [UIButton buttonWithType:UIButtonTypeCustom];
[cellButton addTarget:self action:#selector(selectSite:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
and this is my SourceCode in CustomTableCell
(IBAction) selectSite:(id)sender {}
Assign your indexpath to UIButton's tag like below
cellButton.tag = indexpath.row
and use this tag in your UIButton's Action method
(IBAction) selectSite:(id)sender {
int value = [sender tag];
}
and set it back to cellForRowAtIndexpath method
Related
I am trying to change the color of a button when pressed that is in a tableviewCell. However my code changes the color of every button in the table and not just the one in the cell I selected,
How would I go about just changing the color of the button I pressed.
Please see my code below,
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
UIButton *addNotesButton = (UIButton *)[cell viewWithTag:106];
[addNotesButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Test";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
UIButton *addNotesButton = (UIButton *)[cell viewWithTag:106];/
[addNotesButton addTarget:self action:#selector(addNotes :) forControlEvents:UIControlEventTouchUpInside];
}
The main issue might be in your cellForRowAtIndexPath: method. UITableView cells are re-used as they are displayed on the screen. dequeueReusableCellWithIdentifier: method returns a cell if it has been marked as ready for reuse. You must have seen this method of UITableView being used in cellForRowAtIndexPath: method. (See this link)
So in cellForRowAtIndexPath: you will have to configure each cell as it is being loaded or else it will display old values (since the cells are being reused).
You can either declare a property or a simple variable of type NSIndexPath.Let the variable be called _selectedIndexPath. Then in didSelectRowAtIndexPath: you can assign this property to the indexPath selected.
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
NSArray *indexPaths = nil;
if (_selectedIndexPath) {
indexPaths = #[_selectedIndexPath, indexPath];
} else {
indexPaths = #[indexPath];
}
_selectedIndexPath = indexPath;
[tableView reloadRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
}
- (void)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Your Cell Identifier"];
UIButton *addNotesButton = (UIButton *)[cell viewWithTag:106];
if (indexPath.row == _selectedIndexPath.row) {
[addNotesButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
} else {
[addNotesButton setTitleColor:[UIColor clearColor] forState:UIControlStateNormal];
}
}
You don't need to change color manually in did select row at index path. Just set the color for UIControlStateSelected and on the action of button tap set the buttons selected property to YES. From your code i think this should work.
inside cell for row at index path method
[addNotesButton setTitleColor:[UIColor blueColor] forState:UIControlStateSelected];
and in button action method
-(IBAction)addNotes:(id)sender
{
UIButton *button = (UIButton*)sender;
buttons.selected = !button.isSelected;
}
I think this will work.
After trying everything and failed. I ended up having a hidden value in each row that would change when the button is pressed. So the code reads the value then configures the button for each row.
I am developing one app and i have one requirement that. I have to handle the Favourite button on custom cells like. i am creating the custom button with image on cell and setting unselected type Favourite image i am giving by default once user click on the Favourite button on cell i am changing the button image like selected favourite. I am using the following code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #“CustomCell”;
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.favButton.tag = indexPath.section;
[cell.favButton addTarget:self action:#selector(handleFavouriteButton:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
Button Action:
-(void)handleFavouriteButton:(id)sender
{
UIButton *button = sender;
NSLog(#"selected favourite button tag %li", (long)button.tag);
if (button.selected) {
[button setBackgroundImage:[UIImage imageNamed:#"favourites-normal.png"] forState:UIControlStateNormal];
}
else{
[button setBackgroundImage:[UIImage imageNamed:#"favourites-Selected.png"] forState:UIControlStateNormal];
}
button.selected=!button.selected;
}
Using the above code i am able to change the change the Favourite button from normal to selected and selected to normal but problem is when i select the favourite button on first row it is changing 6 and 11 Ect.. rows also.
Can anybody suggest me right way to do this
Thanks in advance.
That button action and all things are looks fine. You need to save selected Button index as a tag in to the NSMutableArray like following example:
In.h Class:
interface myclass : UIViewController{
}
#property (strong, nonatomic) NSMutableArray *arrcontainstate;
In.m Class:
- (void)viewDidLoad {
[super viewDidLoad];
_arrcontainstate=[NSMutableArray array];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #“CustomCell”;
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.favButton.tag = indexPath.row;
if ( [_arrcontainstate containsObject:indexPath.row]) {
[cell.favButton setBackgroundImage:[UIImage imageNamed:#"favourites-Selected.png"] forState:UIControlStateNormal];
}
else {
[cell.favButton setBackgroundImage:[UIImage imageNamed:#"favourites-normal.png"] forState:UIControlStateNormal];
}
[cell.favButton addTarget:self action:#selector(handleFavouriteButton:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
-(void)handleFavouriteButton:(id)sender
{
UIButton *button = sender;
button.selected=!button.selected;
NSLog(#"selected favourite button tag %li", (long)button.tag);
if (button.selected) {
[_arrcontainstate addObject:button.tag];
[button setBackgroundImage:[UIImage imageNamed:#"favourites-Selected.png"] forState:UIControlStateNormal];
}
else
{
[_arrcontainstate removeObject:button.tag];
[button setBackgroundImage:[UIImage imageNamed:#"favourites-normal.png"] forState:UIControlStateNormal];
}
}
As you are reusing the cell, the image of the button is not changing. First cell is reused in 6th and 11th cell so the button image remains selected. Use this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #“CustomCell”;
CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
cell.favButton.tag = indexPath.section;
[cell.favButton setBackgroundImage:[UIImage imageNamed:#"favourites-normal.png"] forState:UIControlStateNormal];
[cell.favButton addTarget:self action:#selector(handleFavouriteButton:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
I want to add some buttons to custom cell, when I click the button and other buttons also change. How can I click a button without changing the other buttons?
enter code here
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"cell";
SViewTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[SViewTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:identifier];
}
cell.cellButton.tag = indexPath.row;
[cell.cellButton addTarget:self action:#selector(clickMe:)
forControlEvents:UIControlEventTouchUpInside];
return cell;
}
- (void)clickMe:(UIButton *)sender
{
SViewTableViewCell *cell = (SViewTableViewCell *)[[sender superview]superview];
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
if (sender.tag == 0) {
if ([sender.titleLabel.text isEqualToString:openStr]) {
[sender setTitle:closeStr forState:UIControlStateNormal];
}
else{
[sender setTitle:openStr forState:UIControlStateNormal];
}
}
}
I think it's a issue about tableView cell reuse again, you should set the button title in cellForRow to keep reuse cell have a correct title, you should try code like this:
openDict is a NSMutableArray you should define, and this just a example.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"cell";
SViewTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[SViewTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:identifier];
[cell.cellButton addTarget:self action:#selector(clickMe:)
forControlEvents:UIControlEventTouchUpInside];
}
NSString *key = [NSString stringWithFormat:#"%d-%d", indexPath.row, indexPath.section];
if (openDict[key] && [openDict[key] boolValue]) {
[sender setTitle:openStr forState:UIControlStateNormal];
}
else{
[sender setTitle:closeStr forState:UIControlStateNormal];
}
cell.cellButton.tag = indexPath.row;
return cell;
}
- (void)clickMe:(UIButton *)sender
{
SViewTableViewCell *cell = (SViewTableViewCell *)[[sender superview]superview];
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
if (sender.tag == 0) {
NSString *key = [NSString stringWithFormat:#"%d-%d", indexPath.row, indexPath.section];
if (openDict[key] && [openDict[key] boolValue]) {
openDict[key] = #(0);
[sender setTitle:closeStr forState:UIControlStateNormal];
}
else{
openDict[key] = #(1);
[sender setTitle:openStr forState:UIControlStateNormal];
}
}
}
Please set tag for each button in custom tableViewCell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"cell";
SViewTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[SViewTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:identifier];
}
UIButton *button1 = (UIButton *)[cell viewWithTag:1];
UIButton *button2 = (UIButton *)[cell viewWithTag:2];
[button1 addTarget:self action:#selector(clickMe:)
forControlEvents:UIControlEventTouchUpInside];
[button2 addTarget:self action:#selector(clickMe:)
forControlEvents:UIControlEventTouchUpInside];
return cell;
}
To add a button to a UITableViewCell you should do it at the time you configure the cell in cellForRowAtIndexPath - this is after you get the cell to reuse. If you want to add a button to a small number of cells you should cause that cell to be reloaded using UITableView's – reloadRowsAtIndexPaths:withRowAnimation: method or reloadData to give you the opportunity to reload all cells.
Any subview you add to a cell should be added to the cell's contentView as a subview. You should remove all such views in prepareForReuse or you could find cell reuse makes extra buttons appear in cells you don't want to have buttons. Because of the need to prepare cells for reuse it is probably best to subclass UITableViewCell and to provide methods on the subclass to add buttons.
Another way is to register multiple kinds of cells for reuse with the table view, choosing what kind of cell to retrieve and use based on the data backing your table view. This is as simple as using registerClass:forCellReuseIdentifier: once for each kind of cell, then applying right reuse identifier in dequeueReusableCellWithIdentifier:forIndexPath: - you'll still be subclassing the cell objects but you configure them further in the class rather than at the time they are dequeued.
Use the code below:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *identifier = #"cell";
SViewTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[SViewTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
cell.cellButton.tag = indexPath.row;
[cell.cellButton addTarget:self action:#selector(clickMe:)
forControlEvents:UIControlEventTouchUpInside];
return cell;
}
- (void)clickMe:(UIButton *)sender {
SViewTableViewCell *cell = (SViewTableViewCell *)[[[sender superview]superview] superview];
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
[self keepSelectionRemainsSameForIndexPath:indexPath andSender:sender];
}
- (void)keepSelectionRemainsSameForIndexPath:(NSIndexPath *)indexPath andSender:(UIButton *)sender {
if (sender.tag == indexPath.row) {
if ([sender.titleLabel.text isEqualToString: openStr]) {
[sender setTitle:closeStr forState:UIControlStateNormal];
} else {
[sender setTitle: openStr forState:UIControlStateNormal];
}
}
}
This subject is all over the stackoverflow but I couldn't find a fitting solution.
I have button on each UITableViewCell.
Here is how I create the cell.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ExaminationCell"];
UIButton *clipButton = (UIButton *)[cell viewWithTag:3];
MedicalExamination *examination = [objects objectAtIndex:indexPath.row];
[clipButton addTarget:self action:#selector(examinatonClicked:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
Here is the method thah should handle the button click:
-(void)examinatonClicked:(MedicalExamination*)examination
{
}
How do I pass examination object to examinatonCommentsClicked method? Obviously the object is different for each cell...
A somewhat hacky thing that I'll do, is I'll use the UIButton's tag attribute to pass the row number so I can pull the object from the array that's backing my table.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"ExaminationCell"];
UIButton *clipButton = (UIButton *)[cell viewWithTag:3];
clipButton.tag = indexPath.row //Set the UIButton's tag to the row.
MedicalExamination *examination = [objects objectAtIndex:indexPath.row];
[clipButton addTarget:self action:#selector(examinatonClicked:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
-(void)examinatonClicked: (id)sender
{
int row = ((UIButton *)sender).tag;
MedicalExamination *examination = [objects objectAtIndex: row];
//Profit!
}
I think you have to add button in uitableviewCell through xib(custum cell) and then connect it through iboutlet.
I implemented a UIButton in every cell of my UITableView and set an action for this button. Now I'm trying to find out which of these buttons was tapped:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
<...>
UIButton *but=[UIButton buttonWithType:UIButtonTypeRoundedRect];
but.frame= CGRectMake(275, 5, 40, cell.frame.size.height-10);
[but setTitle:#"Map" forState:UIControlStateNormal];
[but addTarget:self action:#selector(Map:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:but];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
return cell;
}
- (IBAction) Map: (id) sender {
NSIndexPath *indexPath = [[NSIndexPath alloc] init];
indexPath = [tableView indexPathForCell:(UITableViewCell*)[[sender superview]superview]];
[delegate callMap: [[[data objectAtIndex:indexPath.section]
objectAtIndex:indexPath.row+1]
objectAtIndex:kNameInArray]
: [[[[data objectAtIndex:indexPath.section]
objectAtIndex:indexPath.row+1]
objectAtIndex:kXcoordinateInArray] doubleValue]
: [[[[data objectAtIndex:indexPath.section]
objectAtIndex:indexPath.row+1]
objectAtIndex:kYcoordinateInArray] doubleValue]
];
}
But it always sends data[0][1][*] elements to the delegate. I mean indexPath always has 0 raw and 0 section. Where is my mistake?
Do the following:
add the button inside your if (cell == nil) { ... } method or else you will have lots of buttons inside the same cell when your cell is reused.
Set cell.contentViow.tag = SomeValueIdentifyingYourData (some int value representing your model.. maybe just the index of your object array..) before returning the cell.
Inside your Map: method you can access the value again with ((UIButton)sender).superview.tag and make your decisions based on that value