UITableViewCell add button - ios

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];
}
}
}

Related

How to add radio button to uitableview?

I added button to table view cell, i want to select one button out of all when user tap on cell
- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"cell";
UITableViewCell *cell = [theTableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
_radioButton = [UIButton buttonWithType:UIButtonTypeCustom];
_radioButton.frame = CGRectMake(30, 0, 30, 30);
[_radioButton setImage:[UIImage imageNamed:#"radio_empty.png"] forState:UIControlStateNormal];
[_radioButton setImage:[UIImage imageNamed:#"radio.png"] forState:UIControlStateSelected];
cell.accessoryView = _radioButton;
_radioButton.tag = indexPath.row;
}
if ([indexPath isEqual:selectedIndex])
{
_radioButton.selected = YES;
}
else
{
_radioButton.selected = NO;
}
cell.textLabel.text = [self.Option objectAtIndex:indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)theTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
selectedIndex = indexPath;
[theTableView reloadData];
//I tried this also but not working
if (_radioButton.tag == indexPath.row) {
[_radioButton setImage:[UIImage imageNamed:#"radio.png"] forState:UIControlStateSelected];
}
}
I tried a lot. But it's not working.
I want to show selected image when user tap on cell. Either if we use button or image view
I got the solution like this.
NSString *selectedIndex;
- (void)tableView:(UITableView *)theTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[theTableView deselectRowAtIndexPath:indexPath animated:NO];
if(indexPath.row != [selectedIndex intValue]) {
// reset the active account
selectedIndex = [#(indexPath.row) stringValue];
// tell the table to rebuild itself
[theTableView reloadData];
}
}
- (UITableViewCell *)tableView:(UITableView *)theTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"cell";
UITableViewCell *cell = [theTableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
if(indexPath.row == [selectedIndex intValue]) {
cell.imageView.image = [UIImage imageNamed:#"radio.png"];
}
else {
cell.imageView.image = [UIImage imageNamed:#"radio_empty.png"];
}
cell.textLabel.text = [self.Option objectAtIndex:indexPath.row];
return cell;
}

checkBox action event in uitableviewcell

I am having custom-cell in which i put the UIButton as the CheckBox.
I want the array of selected checkBox indexPath in ViewController.
I am trying to set the UIButton Action event into the ViewController but it is not accessible. Here is my Code,
-(UITableViewCell *)tableView:(UITableView *)tableView1 cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CustomTableViewCellSaveSearchTableViewCell *cell = [tableView1 dequeueReusableCellWithIdentifier:#"SaveSearchCell"];
if(!cell)
{
cell = [[[NSBundle mainBundle]loadNibNamed:#"CustomTableViewCellSaveSearchTableViewCell" owner:self options:nil]objectAtIndex:0];
}
[self setText:cell];
[cell.btnDelete addTarget:self action:#selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
cell.btnDelete.tag = indexPath.row;
return cell;
}
-(void)btnClick : (UIButton *)btn
{
// I Can't accaes this method.
}
How can i get this.
UITableViewCells have a state of their own to reflect if they are selected or not. You don't need a button in the cells (it is discouraged for UX reasons anyway). Check here for a tutorial.
Do according to these three floowing method.
- (void)viewDidLoad {
[super viewDidLoad];
chekMarkArray = [[NSMutableArray alloc]init];
int totalData = 10;
chekMarkArray=[[NSMutableArray alloc] initWithCapacity:totalData];
for (int i=0; i<totalData; i++) {
[chekMarkArray addObject:#(0)];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UIButton *testButton;
if (cell == nil ||1) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
testButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
testButton.frame = CGRectMake(100, 5,25, 25);
testButton.tag = indexPath.row;
BOOL selectindex = [[chekMarkArray objectAtIndex:indexPath.row] boolValue];
if (!selectindex) {
testButton.backgroundColor = [UIColor greenColor];
}else{
testButton.backgroundColor = [UIColor redColor];
}
[testButton addTarget:self action:#selector(DropDownPressed:) forControlEvents:UIControlEventTouchDown];
[cell addSubview:testButton];
}
return cell;
}
checked button action
-(void)btnClick : (UIButton *)btn
{
UIButton *button = (UIButton*)sender;
BOOL currentStatus = [[chekMarkArray objectAtIndex:button.tag] boolValue];
//deselect all selection
for (int i=0;i<chekMarkArray.count;i++) {
[chekMarkArray replaceObjectAtIndex:i withObject:#(0)];//comment this line for multiple selected button
}
//select current button
[chekMarkArray replaceObjectAtIndex:button.tag withObject:#(!currentStatus)];
[self.tableView reloadData];
}
You may use this code instead of button
first Alloc NsmutableArray in ViewDidLoad
and put an Button outside Tableview to complete your action.
then add
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if(cell.accessoryType == UITableViewCellAccessoryNone) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
[selectedRowsArray addObject:[arrShareTickets objectAtIndex:indexPath.row]];
}
else {
cell.accessoryType = UITableViewCellAccessoryNone;
[selectedRowsArray removeObject:indexPath];
}
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

UITableView CustomCell button set JsonParsing data

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

how to stop the display button click (change button image) in other cell (clicked cell image is changed ) when uitableview scroll?

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1; //count of section
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return 30; //count number of row from counting array hear cataGorry is An Array
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *testword=#"pass";
if ([testword isEqualToString:#"pass"]) {
static NSString *MyIdentifier = #"cell1";
TextTableViewCell *cell ;
cell= [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
cell.lblText.text=[NSString stringWithFormat:#"textcelll= %i", indexPath.row+1];
cell.btnTextbox.tag=indexPath.row;
[cell.btnTextbox addTarget:self action:#selector(customActionPressed:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}else{
static NSString *MyIdentifier1 = #"cell2";
ImageTableViewCell *cell1 = [tableView dequeueReusableCellWithIdentifier:MyIdentifier1];
return cell1;
}
}
-(void)customActionPressed:(UIButton*)sender{
CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView1];
NSIndexPath *indexPath = [self.tableView1 indexPathForRowAtPoint:buttonPosition];
TextTableViewCell *cell = (TextTableViewCell*)[self.tableView1 cellForRowAtIndexPath:indexPath];
if (indexPath != nil)
{
int currentIndex = indexPath.row;
NSLog(#"currentIndex == %d",currentIndex);
int tableSection = indexPath.section;
NSLog(#"tableSection == %d",tableSection);
}
if (!cell.btnTextbox.isSelected ){
cell.btnTextbox.selected=YES;
[cell.btnTextbox setImage:[UIImage imageNamed:#"checkClick.png"] forState:UIControlStateNormal];
NSLog(#"button tag %i",cell.btnTextbox.tag);
NSLog(#"check click");
}else{
cell.btnTextbox.selected=NO;
[cell.btnTextbox setImage:[UIImage imageNamed:#"check.png"] forState:UIControlStateNormal];
NSLog(#"check ");
}
in simulator , when i am clicked the button in first row (indexpath.row=0) then i am scrolling tableview, button click will auto display in 7th row (indexpath.row=6)
Question is ,i want to know , what happened in really and how to avoid this (when i'm scrolling)?
Since cells are being reused, you have to (in your cellForRowAtIndexPath) to set image to one state or another (to set one image or another).
What really happen is that you set Image for one cell but that cell is being reused through whole table. You use only 5(lets say that is how much you cells can fit into one screen) cells and when you load next you actually reuse the one with an image.
So, in your cellForRowAtIndexPath you will have to check if the button state is selected or not and then assign appropriate image.
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *testword=#"pass";
if ([testword isEqualToString:#"pass"]) {
static NSString *MyIdentifier = #"cell1";
TextTableViewCell *cell ;
cell= [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
cell.lblText.text=[NSString stringWithFormat:#"textcelll= %i", indexPath.row+1];
cell.btnTextbox.tag=indexPath.row;
if (cell.btnTextbox.isSelected ){
[cell.btnTextbox setImage:[UIImage imageNamed:#"checkClick.png"] forState:UIControlStateNormal];
}else{
[cell.btnTextbox setImage:[UIImage imageNamed:#"check.png"] forState:UIControlStateNormal];
}
[cell.btnTextbox addTarget:self action:#selector(customActionPressed:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}else{
static NSString *MyIdentifier1 = #"cell2";
ImageTableViewCell *cell1 = [tableView dequeueReusableCellWithIdentifier:MyIdentifier1];
return cell1;
}
}
For completness sake, I would also suggest you to use Accessory type as well as Xib files for these kind of cells. You can set it in storyboard under accessory dropdown or through code:
cell.accessoryType = UITableViewCellAccessoryCheckmark;

Actions for UIButtons in UITableViewCells

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

Resources