I have seen and checked multiple questions regarding adding an UIButton to a UITableViewCell but somehow I did not manage to find the exact problem that I am facing. When adding an UIButton to an UITableViewCell, the cell's text label overlaps with the button. The button is in the beginning of the row and it should be followed by the text label. I am most probably doing something wrong, but I can not find what. Here is my code for cellForRowAtIndex:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
UITableViewCell *cell=[self._tableView dequeueReusableCellWithIdentifier:#"event"];
Event* event =[self eventForIndexPath:indexPath];
if(cell==nil)
cell=[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:#"event"];
[[cell textLabel] setText:event.customer.name];
if(event.startTime!=nil)
[[cell detailTextLabel] setText:event.startTime];
cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
UIButton *cellButton =(UIButton*) [cell.contentView viewWithTag:CELL_BUTTON_TAG];
if(cellButton == nil){
UIButton *cellButton = [UIButton buttonWithType:UIButtonTypeCustom];
cellButton.tag=CELL_BUTTON_TAG;
[cellButton setFrame:CGRectMake(0.0f, 0.0f, 44.0f, cell.frame.size.height)];
[cellButton setImage:[UIImage imageNamed:#"van_green.png"] forState:UIControlStateNormal];
[cellButton setImage:[UIImage imageNamed:#"location.png"]forState:UIControlStateSelected];
[cellButton addTarget:self action:#selector(carButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
cellButton.layer.borderWidth = 0.0;
[cell.contentView addSubview:cellButton];
}
return cell;
}
Sorry but your code is completely wrong..you are using an incorrect way and also you are adding a button each time.
The tableViewCell are REUSED so you have to add buttons and other UI elements just when you INIT the cell and not each time, or your app will finish in memory warning, crash, not fluid etc.
The correct way to do what you want to do is create your CustomTableViewCell subclassing the class UITableViewCell and add your labels and buttons. It is really simple:
1) Create a new file CustomSearchCell object that extends UITableViewCell:
CustomSearchCell.h
#import <UIKit/UIKit.h>
#interface CustomSearchCell : UITableViewCell
#property (strong, nonatomic) UIButton *button;
#property (strong, nonatomic) UILabel *lblDetails;
#end
CustomSearchCell.m
#import "CustomSearchCell.h"
#implementation CustomSearchCell
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
// Initialization code
_lblDetails = [[UILabel alloc] initWithFrame:CGRectMake(100, 10, 200, 45)];
[_lblDetails setFont:[UIFont systemFontOfSize:20.0]];
[_lblDetails setTextColor:[UIColor blackColor]];
_button = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 44, self.frame.size.height)];
[self.contentView addSubview: _lblDetails];
[self.contentView addSubview: _button];
}
return self;
}
#end
2) In your view controller:
#import "CustomSearchCell.h"
and:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"ListCellIdentifier";
CustomSearchCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell) {
cell = [[CustomSearchCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
//Settings
return cell;
}
Another your problem is when you press the button. You will receive the sender but the tableViewCell will can be used for a different indexPath when you intercept the touch..be careful..the correct way is another..you need to save in some way the actual indexPath when you press the button...
Problem is in this line [cell.contentView addSubview:cellButton];. When your cell going to be reuse, the cell already contains cell button, and you try to add that button again. Just do the below step to resolve this issue.
1) Add button tag to take from base view.
UIButton *cellButton = [UIButton buttonWithType:UIButtonTypeCustom];
cellButton.tag = CELLBUTTONTAG;
2) Check condition view tag and add it to base view as below.
UIButton *cellButton = [cell.contentView viewWithTag:CELLBUTTONTAG];
if(cellButton == nil)
{
UIButton *cellButton = [UIButton buttonWithType:UIButtonTypeCustom];
cellButton.tag = CELLBUTTONTAG;
...
[cell.contentView addSubview:cellButton];
}
You have given cellbutton's y position as 0.0f.That's y overlapping. try to change some value as you need.
[cellButton setFrame:CGRectMake(0.0f, 0.0f, 44.0f, cell.frame.size.height)];
to
[cellButton setFrame:CGRectMake(0.0f, some big value, 44.0f, cell.frame.size.height)];
Related
I created the UITableView programatically, and in my UITableView have 3 rows in the UITableView section. I have a UIButton in 3 rows. Initially, all the buttons of three rows have gray color. If I select the button in the 2nd row, then the button in the 2nd row should be red and the all others gray and so on. Can any one suggest me.
In your cellForRowAtIndexPath
UIButton *button = [[UIButton alloc]initWithFrame:Your Frame];
[button addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
button.tag = indexPath.section;
[cell.contentView addSubview:button];
Then write buttonClicked method
-(void)buttonClicked:(UIButton*)button
{
UIButton *but1;
UIButton *but2;
if (button.tag == 0)
{
but1 = (UIButton *)[self.view viewWithTag:1];
but2 = (UIButton *)[self.view viewWithTag:2];
[but1 setBackgroundColor:[UIColor grayColor]];
[but2 setBackgroundColor:[UIColor grayColor]];
[button setBackgroundColor:[UIColor redColor]];
}
if (button.tag == 1)
{
but1 = (UIButton *)[self.view viewWithTag:0];
but2 = (UIButton *)[self.view viewWithTag:2];
[but1 setBackgroundColor:[UIColor grayColor]];
[but2 setBackgroundColor:[UIColor grayColor]];
[button setBackgroundColor:[UIColor redColor]];
}
if (button.tag == 2)
{
but1 = (UIButton *)[self.view viewWithTag:0];
but2 = (UIButton *)[self.view viewWithTag:1];
[but1 setBackgroundColor:[UIColor grayColor]];
[but2 setBackgroundColor:[UIColor grayColor]];
[button setBackgroundColor:[UIColor redColor]];
}
}
Hope it helps.
Try this:
Create the button as mentioned by patil (look below for his answer) ,and try to give it a tag.
button.tag=indexpath.section;
You need to set target-action of each button.Write the following line in the button action method:
[button setTarget:self action:#selector(someMethod:) forControlEvents:UIControlEventTouchUpInside];
Then implement someMethod: like this:
- (void)someMethod:(UIButton *)sender {
if (sender.tag == 1) {
// do action for button with tag 1
//change color here
[button setBackgroundColor:[UIColor redColor]];
} else if (sender.tag == 2) {
// do action for button with tag 2
} // ... and so on
}
I'm not too fond of the multiple if cases as you would need to re-write a lot when your amount of sections / rows change.
This is a more generic answer but it might not be so easy as the others. It involves created a UIButton subclass and a UITableViewCell subclass.
Create a UIButton subclass with a property to store the NSIndexPath of the cell where the button will be shown on:
//
// IndexPathButton.h
//
//
// Created by You on 28/07/15.
//
//
#import <UIKit/UIKit.h>
#interface IndexPathButton : UIButton
#property (nonatomic) NSIndexPath *indexPath;
#end
There should not be anything implemented in the .m file.
Create a UITableViewCell subclass which has the custom IndexPathButton on it. If you need help creating a custom UITableViewCell I suggest searching on SO or creating a new question.
In your UIViewController with your UITableView do the import of the custom UIButton
#import "IndexPathButton.h"
Also create an class variable to store the selectedIndexPath:
NSIndexPath *selectedButtonIndexPath;
Now we can start changing the UITableViewDataSource method:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellId = #"SomeCell";
YourCustomCellWithButton *cell = [tableView dequeueReusableCellWithIdentifier:cellId];
if (!cell)
{
cell = [[YourCustomCellWithButton alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
}
//Default setup of IndexPathButton on YourCustomCellWithButton
cell.button.backgroundColor = [UIColor grayColor];
cell.button.indexPath = indexPath; //Here we store the indexPath for later use
[cell.button addTarget:self action:#selector(cellButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
//Check here if it should be red or not
if (selectedButtonIndexPath == indexPath)
{
cell.button.backgroundColor = [UIColor redColor];
}
return cell;
}
And the button target action:
-(void)cellButtonPressed:(IndexPathButton*)sender
{
//Set the selectedIndexPath
selectedButtonIndexPath = sender.indexPath;
[yourTableView reloadData];
}
How to detect multiple buttons in tableview cell and my doubt is with example i have 3 buttons in cell if i tap on one button that button will change colour and and if i click indexpath.row=1 cell button that button will color also need to change help me
I did like this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = #"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier];
}
UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button.frame = CGRectMake(10.0, 0.0, self.tableView.frame.size.width/4, 40.0);
button.tag = 100 + indexPath.row*total_buttons_in_a_row;
[button setTitle:[NSString stringWithFormat:#"%ld",(long)button.tag] forState:UIControlStateNormal];
[button addTarget:self action:#selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:button];
UIButton *button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button2.frame = CGRectMake(10.0+self.tableView.frame.size.width/4+10.0, 0.0, self.tableView.frame.size.width/4, 40.0);
button2.tag = 100 + indexPath.row*total_buttons_in_a_row + 1;
[button2 setTitle:[NSString stringWithFormat:#"%ld",(long)button2.tag] forState:UIControlStateNormal];
[button2 addTarget:self action:#selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:button2];
UIButton *button3 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
button3.frame = CGRectMake(10.0+self.tableView.frame.size.width/4*2+10.0, 0.0, self.tableView.frame.size.width/4, 40.0);
button3.tag = 100 + indexPath.row*total_buttons_in_a_row + 2;
[button3 setTitle:[NSString stringWithFormat:#"%ld",(long)button3.tag] forState:UIControlStateNormal];
[button3 addTarget:self action:#selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];
[cell addSubview:button3];
return cell;
}
-(void)btnClicked:(UIButton *)sender{
id selectedButton = [self.view viewWithTag:sender.tag];
if ([selectedButton backgroundColor] == [UIColor redColor]) {
[selectedButton setBackgroundColor:[UIColor clearColor]];
}else{
[selectedButton setBackgroundColor:[UIColor redColor]];
}
}
total_buttons_in_a_row is an Int. In your case define it in viewDidLoad total_buttons_in_a_row=3
P.S - set the Buttons CGRectMake according to your need.
Assign tag to each button using the combination of section & row..
When method assigned to button get called use '%' & '/' for further manipulation.
Let me know if you have any difficulty in implementing it..
Got to your CustomCell.h & right below #import add this code.
#protocol CustomCellDelegate <NSObject>
- (void)buttonActionwith :(NSIndexPath *)indexPath;
#end
Then Add this code right below #interface CustomCell : UITableViewCell
//Manual Properties
#property (strong, nonatomic) NSIndexPath *buttonIndexPath;
//Delegate
#property (nonatomic, weak) id <CustomCellDelegate> delegate;
The use of this NSIndexPath is to identify which cell user selecting.
Then go to CustomCell.m & in your button IBAction method add this code.
[self.delegate buttonActionwith:self.buttonIndexPath];
The meaning of this line of code is that, when the user TouchUpInside the Button in the cell buttonActionwith delegate method calls, if you set this CustomCellDelegate in your UIViewController where the UITableView is, that delegate method will call inside that ViewController too.
Now go to your MainViewController.h & add
CustomCellDelegate
& it will look like this after that,
#interface MainViewController : UIViewController <CustomCellDelegate,,UITableViewDataSource,UITableViewDelegate>
when creating the Custom UITableViewCell in - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath don't forget to add this line of code before return cell;
//Set Cell Values Here
cell.delegate = self; //Setting delegate to self
cell.buttonIndexPath = indexPath;
The modified - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath will look like this,
static NSString *MyIdentifier = #"MyIdentifier"; //Set Identifier for cell
CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier: MyIdentifier]; //init CustomCell
if (cell == nil) { //Check cell is nill or not
NSArray *nib;
nib = [[NSBundle mainBundle] loadNibNamed:#"CustomCell"
owner:self options:nil]; //if cell is nil add CustomCell Xib
for (id oneObject in nib) if ([oneObject isKindOfClass:[CustomCell class]])
cell = (CustomCell *)oneObject;
}
//Set Cell Values Here
cell.buttonIndexPath = indexPath
return cell;
Finally add this method inside MainViewController.m
#pragma mark - SwipeableCellDelegate
- (void)buttonActionwith:(NSIndexPath *)indexPath { //Delegate method
NSLog(#"Button Clicks at index %ld",(long)indexPath.row);
}
This is how to add a single button inside the Cell. you can use this method to more buttons to the cell.
i've created a tableViewCell subclass called TestTableViewCell. i've connected datasource and delegate by using this. The problem is that it does not seem to do anything that i've stated in the subclass, not even changing the background?
self.tableView.delegate = self;
self.tableView.datasource = self;
i've changed the cell class to TestTableViewCell and created an identifier called Cell.
cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = #"Cell";
TestTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (!cell) {
cell = [[TestTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
}
return cell;
}
subclass
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
UIButton *btn1 = [[UIButton alloc] initWithFrame:CGRectMake(CGRectGetWidth(self.frame) - 60, 10, 50, 30)];
[btn1 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn1 setTitle:#"B1" forState:UIControlStateNormal];
[self.contentView addSubview:btn1];
UIButton *btn2 = [[UIButton alloc] initWithFrame:CGRectMake(CGRectGetMinX(btn1.frame), 70, 50, 30)];
[btn2 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[btn2 setTitle:#"B2" forState:UIControlStateNormal];
[self.contentView addSubview:btn2];
UIButton *btn3 = [[UIButton alloc] initWithFrame:CGRectMake(CGRectGetMinX(btn1.frame), 130, 50, 30)];
[btn3 setTitle:#"B3" forState:UIControlStateNormal];
[btn3 setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[self.contentView addSubview:btn3];
UISwipeGestureRecognizer *gesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(moveCover:)];
gesture.direction = UISwipeGestureRecognizerDirectionLeft;
UISwipeGestureRecognizer *gesture2 = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:#selector(moveCover:)];
gesture2.direction = UISwipeGestureRecognizerDirectionRight;
_coverView = [[UIView alloc] initWithFrame:CGRectMake(0, 5, CGRectGetWidth(self.frame), 195)];
_coverView.backgroundColor = [UIColor grayColor];
[self.contentView addSubview:_coverView];
[self addGestureRecognizer:gesture];
[self addGestureRecognizer:gesture2];
self.selectionStyle = UITableViewCellSelectionStyleNone;
}
return self;
}
Assuming you are using Interface Builder and have a UITableView with a 'custom' dynamic prototype cell. Did you assign your TestTableViewCell subclass to the table cell row in IB (like you do for UITableViewController when you create a custom UITableViewController subclass? If you don't do this then when you dequeue your cell, you will get the cell (and default class) as defined in IB, not your custom cell with custom class.
Also, note, that all of the button creation logic, etc. in your subclass could go directly into your custom cell (visually) within IB and you can avoid all that code if you so choose. Just visually design your row in IB then use Assistant Editor to create outlets and actions in your custom cell (TestTableViewCell) header and implementation (.m).
Finally, you don't need to allocate the cell in CellForRowAtIndexPath
I'm trying to implement a table view where all rows have 2 buttons which then do something with the data at the index row they are on.
here is what I have so far:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"NotificationCell";
NotificationCell *cell = (NotificationCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (cell == nil) {
cell = [[NotificationCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
NotificationObject *notification = nil;
notification = [_notificationArray objectAtIndex:indexPath.row];
cell.profileImage.image = notification.profileImage;
cell.profileImage.layer.cornerRadius = cell.profileImage.frame.size.height /2;
cell.profileImage.layer.masksToBounds = YES;
cell.profileImage.layer.borderWidth = 0;
cell.detailTextView.text = notification.action;
UIButton *denyButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
UIButton *acceptButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
//set the position of the button
denyButton.frame = CGRectMake(cell.frame.origin.x + 285, cell.frame.origin.y + 20, 23, 23);
[denyButton setBackgroundImage:[UIImage imageNamed:#"DenyRequest.png"] forState:UIControlStateNormal];
[denyButton addTarget:self action:#selector(denyButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
denyButton.backgroundColor= [UIColor clearColor];
[cell.contentView addSubview:denyButton];
acceptButton.frame = CGRectMake(cell.frame.origin.x + 240, cell.frame.origin.y + 20, 23, 23);
[acceptButton setBackgroundImage:[UIImage imageNamed:#"AcceptRequest.png"] forState:UIControlStateNormal];
[acceptButton addTarget:self action:#selector(AcceptButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
acceptButton.backgroundColor= [UIColor clearColor];
[cell.contentView addSubview:acceptButton];
return cell;
}
-(void)denyButtonPressed:(id)sender{
NSLog(#"buttonPressedDeny");
}
-(void)AcceptButtonPressed:(id)sender{
NSLog(#"buttonPressedAccept");
}
However I am not sure how to find out which index row the selected button was pressed so that I can get the relevant data.
The simplest solution is to assign a tag to each button. For example:
denyButton.tag = 1000 + indexPath.row;
Then on denyButtonPressed:
-(void)denyButtonPressed:(id)sender{
UIButton *b = (UIButton *)sender;
NSInteger row = b.tag - 1000;
NSLog(#"buttonPressedDeny: %d", row);
}
The variable row will hold the index path row where the button was pressed. The addition of 1000 is to avoid collision with other views you may already have.
Let me emphasize that this is the SIMPLEST solution but not the most friendly from a design/architecture point of view.
A more elaborate solution could be to have the buttons as part of NotificationCell, have NotificationCell be the delegate for those buttons, and create a protocol that allows your view controller to be the delegate of each NotificationCell. Then when the button is pressed, it will be handled by NotificationCell, which will pass whatever object is needed to your view controller.
For example, create the following protocol in NotificationCell.h
#protocol NotificationCellDelegate
- (void)denyActionForNotificationObject:(NotificationObject *)notificationObject;
- (void)acceptActionForNotificationObject:(NotificationObject *)notificationObject;
#end
Also add NotificationCell add a property to hold a notification and a delegate:
#property (nonatomic, strong) NotificationObject *notificationObject;
#property (nonatomic, strong) id<NotificationCellDelegate> delegate;
Create a method awakeFromNib (if you are using storyboards)
- (void)awakeFromNib {
[super awakeFromNib];
UIButton *denyButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
UIButton *acceptButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
//set the position of the button
denyButton.frame = CGRectMake(self.contentView.frame.origin.x + 285, self.contentView.frame.origin.y + 20, 23, 23);
[denyButton setBackgroundImage:[UIImage imageNamed:#"DenyRequest.png"] forState:UIControlStateNormal];
[denyButton addTarget:self action:#selector(denyButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
denyButton.backgroundColor= [UIColor clearColor];
[self.contentView addSubview:denyButton];
acceptButton.frame = CGRectMake(self.contentView.frame.origin.x + 240, self.contentView.frame.origin.y + 20, 23, 23);
[acceptButton setBackgroundImage:[UIImage imageNamed:#"AcceptRequest.png"] forState:UIControlStateNormal];
[acceptButton addTarget:self action:#selector(AcceptButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
acceptButton.backgroundColor= [UIColor clearColor];
[cell.contentView addSubview:acceptButton];
}
Implement the selectors you declared:
- (void)denyButtonPressed:(id)sender {
if (_delegate) {
[_delegate denyActionForNotificationObject:_notificationObject];
}
}
- (void)AcceptButtonPressed:(id)sender {
if (_delegate) {
[_delegate acceptActionForNotificationObject:_notificationObject];
}
}
Then in your cellForRowAtIndexPath in your view controller add:
cell.notificationObject = notificationObject;
cell.delegate = self;
Also in your view controller, implement the protocol:
- (void)denyActionForNotificationObject:(NotificationObject *)notificationObject {
// Do something with the notification object
}
- (void)acceptActionForNotificationObject:(NotificationObject *)notificationObject {
// Do something with the notification object
}
I have not tested this in XCode, my apologies if it doesn't compile
Why not work backwards through the view hierarchy and check the button's superview, which should be the content view of the table view cell. Whose superview should be the cell?
-(void)denyButtonPressed:(id)sender{
UIButton *button = (UIButton *)sender;
UIView *contentView = button.superview;
UITableViewCell *cell = contentView.superview;
NSIndexPath * indexPath = self.tableView indexPathForCell:cell];
NSLog(#"row containing button: %d", indexPath.row);
}
I have a subview within UITableViewCell's that contains a UILabel and a UIButton. When I push the button it unselects the UITableViewCell for some reason.
Is there a way to pass the touch event through to its super view? Or is there a different problem all together?
Here is the code for CellForRowAtIndexPath. I plan on creating a custom subclass of UITableViewCell so I can handle cell reuse properly so don't feel the need to mention that.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
CountModel *cellModel = self.viewModel.data[indexPath.row];
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"RootViewControllerMetricCell"];
cell.textLabel.text = cellModel.title;
// Custom background color for selection
UIView *bgColorView = [[UIView alloc] init];
bgColorView.backgroundColor = UIColorFromRGB(0xF3F3F3);
bgColorView.layer.masksToBounds = YES;
[cell setSelectedBackgroundView:bgColorView];
// Construct subview and append to bottom (only visible when selected)
UIView *cellSubView = [[UIView alloc] initWithFrame:CGRectMake(0, 125, cell.frame.size.width, 25)];
// UILabel for display of current count
UILabel *lblCount = [[UILabel alloc] initWithFrame:CGRectMake(15, 0, 25, 25)];
lblCount.text = [NSString stringWithFormat:#"%d", [cellModel.count intValue]];
// Create UIButton for incrementing
UIButton *incrementButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
incrementButton.frame = CGRectMake(45, 0, 25, 25);
[incrementButton setTitle:#"+" forState:UIControlStateNormal];
// Enable touch event for button view
[incrementButton addTarget:self action:#selector(countButtonTouchDown:) forControlEvents:UIControlEventTouchDown];
[cellSubView addSubview:lblCount];
[cellSubView addSubview:incrementButton];
[cell addSubview:cellSubView];
return cell;
}
How about you add the [self.tableView cellForRowAtIndePath:] setSelected:] inside the function responding to the button press to reinstate the same selected/ deselected state.
UPDATE:
Shift the code inside the didSelectCellAtIndexPath to another function, say performActionOnSelectionOfCellAtIndexPath and call performActionOnSelectionOfCellAtIndexPath from inside the didSelectCellAtIndexPath with the indexPath and also call performActionOnSelectionOfCellAtIndexPath from the function responding to the button press.