Objective-c custom table cell buttons - ios

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

Related

Hiding buttons on a UITableViewCell

I have two UIButtons on each UITableViewCell and I'm basically trying to set both of the buttons to hide when one or the other is pressed. The only thing I found online are just about using .tag to record a press.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString * indentifer = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:indentifer forIndexPath:indexPath];
// Configure the cell...
cell.textLabel.text = [self.random objectAtIndex:indexPath.row];
UIButton * acecept = [UIButton buttonWithType:UIButtonTypeRoundedRect];
acecept.frame = CGRectMake(cell.bounds.origin.x + 200, cell.bounds.origin.y + 20 , 50, 30);
[acecept setTitle: #"Yes" forState:UIControlStateNormal];
[acecept addTarget:self action:#selector(waffles:) forControlEvents:UIControlEventTouchUpInside];
acecept.backgroundColor = [UIColor whiteColor];
[cell.contentView addSubview:acecept];
self.deny = [UIButton buttonWithType:UIButtonTypeRoundedRect];
_deny.frame = CGRectMake(cell.bounds.origin.x + 250, cell.bounds.origin.y + 20 , 50, 30);
[_deny setTitle: #"no" forState:UIControlStateNormal];
[_deny addTarget:self action:#selector(cereal:) forControlEvents:UIControlEventTouchUpInside];
_deny.backgroundColor = [UIColor whiteColor];
[cell.contentView addSubview:_deny];
UIButton * button = (UIButton *) acecept;
button.tag = button.tag+1;
/* if (acecept.hidden) {
[_deny setHidden:YES];
} */
return cell;
}
This is how I'm hiding them once they are pressed:
-(IBAction) waffles:(id)sender {
NSLog(#"waffles");
UIButton * button = (UIButton *) sender;
button.tag = button.tag+1;
NSLog(#"%ld", (long)button.tag);
waff = button.tag;
[sender setHidden:YES];
if(sender.hidden == YES){
[self.deny setHidden:YES];
}
}
-(IBAction)cereal:(id)sender{
NSLog(#"cereal");
[sender setHidden:YES];
}
I've tried multiple if statements and tagging the button. I think I need to somehow get the number of the cell view at which one of the button is pressed at, then place that in each IBAction.
I have made changes in your code..
Check below code
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString * indentifer = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:indentifer forIndexPath:indexPath];
// Configure the cell...
cell.textLabel.text = [self.random objectAtIndex:indexPath.row];
UIButton * acecept = [UIButton buttonWithType:UIButtonTypeRoundedRect];
acecept.frame = CGRectMake(cell.bounds.origin.x + 200, cell.bounds.origin.y + 20 , 50, 30);
[acecept setTitle: #"Yes" forState:UIControlStateNormal];
[acecept addTarget:self action:#selector(waffles:) forControlEvents:UIControlEventTouchUpInside];
acecept.backgroundColor = [UIColor whiteColor];
acecept.tag = 1;
[cell.contentView addSubview:acecept];
UIButton * deny = [UIButton buttonWithType:UIButtonTypeRoundedRect];
deny.frame = CGRectMake(cell.bounds.origin.x + 250, cell.bounds.origin.y + 20 , 50, 30);
[deny setTitle: #"no" forState:UIControlStateNormal];
[deny addTarget:self action:#selector(cereal:) forControlEvents:UIControlEventTouchUpInside];
deny.backgroundColor = [UIColor whiteColor];
deny.tag = 2;
[cell.contentView addSubview:_deny];
return cell;
}
-(IBAction) waffles:(id)sender {
NSLog(#"waffles");
UIButton *aceceptBtn = (UIButton *) sender;
[aceceptBtn setHidden:YES];
UIButton *denyBtn = [aceceptBtn.superview viewWithTag:2];
[denyBtn setHidden:YES];
}
-(IBAction)cereal:(id)sender{
NSLog(#"cereal");
UIButton *denyBtn = (UIButton *) sender;
[denyBtn setHidden:YES];
UIButton *aceceptBtn = [denyBtn.superview viewWithTag:1];
[aceceptBtn setHidden:YES];
}
The approach that you are using is not right.
You need to create a custom tableview cell with two buttons.
And in that cell's .m class, you can write IBActions for those two buttons.
And in those IBActions, you can hide both the buttons.
In .h declares buttons in this way (with an Outlet)
#property (weak, nonatomic) IBOutlet UIButton *buttonOne;
#property (weak, nonatomic) IBOutlet UIButton *buttonTwo;
In .m:
-(IBAction)presentPrincipalViewController:(id)sender {
[self.buttonOne setHidden:YES];
[self.buttonTwo setHidden:YES];
}
if you want to hide all buttons:
-(IBAction)presentPrincipalViewController:(id)sender {
for (UIButton* someButton in self.view.subviews) {
[someButton setHidden:YES];
}
}

Change background color of UIButton on UITableViewCell in section

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

Can't get my UIButton in TableViewCell to fire

I have a subclassed UITableViewCell with a "Start" and "Done" button on each cell. The "Done" button gets created after you press "Start". If I have my button press logic in my subclassed UITableViewCell file, it triggers just fine.
But I realize I actually want the button press to trigger the editing mode in the table view, so I want to have some logic in my cellForRowAtIndexPath instead of the subclassed file. But then I can't get the button to fire :(
What am I doing wrong or not understanding?
My TableViewCell.m
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
self.startButton = [[UIButton alloc] initWithFrame:CGRectMake(250 + 0.60 * self.screenWidth, 65, 150, 30)];
[self.startButton addTarget:self action:#selector(onStartButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
self.startButton.backgroundColor = [UIColor colorWithRed:0.16 green:0.65 blue:0.19 alpha:1.0];
btnLayer = [self.startButton layer];
[btnLayer setMasksToBounds:YES];
[btnLayer setCornerRadius:5.0f];
[self.startButton setTag:1];
[self addSubview:self.startButton];
}
- (void)onStartButtonPressed:(id)sender {
if (self.countdown)
{
[self beginDoneButton];
}
}
-(void)beginDoneButton {
self.startButton.enabled = NO;
self.startButton.hidden = YES;
self.doneButton = [[UIButton alloc] initWithFrame:CGRectMake(250 + 0.60 * self.screenWidth, 65, 150, 30)];
self.doneButton.backgroundColor = [UIColor colorWithRed:0.16 green:0.65 blue:0.19 alpha:1.0];
CALayer *btnLayer = [self.doneButton layer];
[btnLayer setMasksToBounds:YES];
[btnLayer setCornerRadius:5.0f];
[self.doneButton setTitle:#"Done "forState:UIControlStateNormal];
[self addSubview:self.doneButton];
}
My TableViewController.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// get index of Data
int index = (int) indexPath.row;
id order = [orders objectAtIndex:index];
TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"orderCell"];
cell = [[OrderTableViewCell alloc] initWithStyle:UITableViewCellSelectionStyleNone reuseIdentifier:#"orderCell"];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
cell.customerNameLabel.text = [order objectForKey:#"first_name"];
cell.orderLabel.text = [NSString stringWithFormat: #"Order #%#", [order objectForKey:#"order_id"]];
[cell.customerImageView sd_setImageWithURL:[NSURL URLWithString: [order objectForKey:#"profile_image"]]
placeholderImage:[UIImage imageNamed:#"stub"]
];
[cell.messageButton setTitle:#"Message" forState:UIControlStateNormal];
// This doesn't work
[cell.doneButton addTarget:self action:#selector(onDoneButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
return cell;
}
// This doesn't get fired
- (IBAction)onDoneButtonPressed:(id)sender {
NSLog(#"pressed");
UITableViewCell *cell = (UITableViewCell *)[sender superview];
NSIndexPath *pathToCell = [self.tv indexPathForCell:cell];
}
How about this:
In your custom table view cell, create your buttons but don't add target/actions to them Just connect them to an IBOutlet in your cell's class.
Then in your cellForRowAtIndexPath, cast your cell pointer to your custom cell class, and use cell.button1Outlet outlet to set the target/action on the buttons with the view controller as the target. Now your cell buttons will invoke a method in the view controller, not in the cell, even though the outlets belong to the cells.

iOS - Custom AccessoryView not showing in UITableViewCell

I have tried to show a custom view with an accept button and decline button (as subviews) in a table view cell. I have the following code implemented:
tableView: cellForRowAtIndexPath: method
...
if ([status isEqualToString:#"pending"] || [status isEqualToString:#"declined"]){
cell.accessoryView = [self setAccessoryViewForCell:cell];
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
...
- (UIView *)setAccessoryViewForCell:(UITableViewCell *)cell
{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(192, 0, 128, 44)];
UIButton *acceptButton = [[UIButton alloc] initWithFrame:CGRectMake(2, 5, 60, 34)];
UIButton *declineButton = [[UIButton alloc] initWithFrame:CGRectMake(66, 5, 60, 34)];
[acceptButton setTitle:#"A" forState:UIControlStateNormal];
[declineButton setTitle:#"D" forState:UIControlStateNormal];
[acceptButton addTarget:self action:#selector(acceptButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[declineButton addTarget:self action:#selector(declineButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[view addSubview:acceptButton];
[view addSubview:declineButton];
return view;
}
I have tried to debug it, but the methods are called appropriately.
Finally, the problem was not in the cellForRowAtIndexPath: method, but in the setAccessoryViewForCell: method. When creating a view for containing two buttons as subviews I really should not have used literal values for the frames. Instead of setting a view for accessoryView property, I rewrote the whole cellForRowAtIndexPath: method and added a subview to the cell's contentView.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *identifier = #"notificationsCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (!cell){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:identifier];
}
PFObject *user = [self.objects objectAtIndex:indexPath.row];
NSString *firstName = [user objectForKey:#"firstName"];
NSString *lastName = [user objectForKey:#"lastName"];
cell.textLabel.text = [NSString stringWithFormat:#"%# %#", firstName, lastName];
UIView *view = [UIView new];
view.frame = CGRectMake(230, 2, 80, 40);
view.backgroundColor = [UIColor whiteColor];
UIButton *acceptButton = [UIButton buttonwithType:UIButtonTypeCustom];
UIButton *declineButton = [UIButton buttonWithType:UIButtonTypeCustom];
[acceptButton setTitle:#"" forState:UIControlStateNormal];
[declineButton setTitle:#"" forState:UIControlStateNormal];
[acceptButton setImage:[UIImage imageNamed:#"Ok.png"] forState:UIControlStateNormal];
[declineButton setImage:[UIImage imageNamed:#"Close.png"] forState:UIControlStateNormal];
[acceptButton addTarget:self action:#selector(acceptButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
[declineButton addTarget:self action:#selector(declineButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
acceptButton.frame = CGRectMake(CGRectGetMinX(view.bounds), CGRectGetMinY(view.bounds), CGRectGetWidth(view.bounds)/2, CGRectGetHeight(view.bounds));
declineButton.frame = CGRectMake(CGRectGetMidX(view.bounds), CGRectGetMinY(view.bounds), CGRectGetWidth(view.bounds)/2, CGRectGetHeight(view.bounds));
[view addSubview:acceptButton];
[view addSubview:declineButton];
[cell.contentView addSubview:view];
return cell;
}
The main difference was that when setting the frames for each button, I used literal values (not a good practice) and now I used the CGRect functions CGRectGetMinX(CGRect rect), CGRectGetMinY(CGRect rect), CGRectGetWidth(CGRect rect), CGRectGetMidX(CGRect rect) and CGRectGetHeight(CGRect rect) to get more accurate values for setting each button's frame. This was a misunderstanding of how a UIView's frames work, I recommend always to use these functions to get the origin and size of subviews and not to use literal values.
The problem appeared to be you are not returning the UIView from setAccessoryViewForCell method.
return view;
Please return the view from the mentioned method, it might solve your problem.

Detect which button was clicked in a grouped UITableView

I have a grouped UITableView (this one has 4 sections) and several rows each. I have programatically created 2 buttons in each of the cells.
This is how I am creating the UITableViewCell. In this code, I am trying to detect the indexPath.row and the indexPath.section of the button that was pressed and pass it to the method. How am I able to do this ?
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *cellId = #"Cell";
UITableViewCell *cell ;//= [tableView dequeueReusableCellWithIdentifier:nil];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
}
NSString *docTitle = [currentDocument objectForKey:#"displayname"];
UIView *cellView = [[UIView alloc] initWithFrame:CGRectMake(cell.contentView.frame.origin.x+5, cell.contentView.frame.origin.y, cell.contentView.frame.size.width, cell.contentView.frame.size.height)];
UILabel *cellTitle = [[UILabel alloc] initWithFrame:CGRectMake(cellView.frame.origin.x + 5, cellView.frame.origin.y + 5, cellView.frame.size.width - 10, 25)];
cellTitle.backgroundColor = [UIColor clearColor];
cellTitle.text = docTitle;
[cellView addSubview:cellTitle];
[cell.contentView addSubview:cellView];
UIButton *viewDocumentButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[viewDocumentButton setTitle:#"View Online" forState:UIControlStateNormal];
viewDocumentButton.frame = CGRectMake(cellView.frame.origin.x + 5, cellTitle.frame.origin.y + cellTitle.frame.size.height + 5, 150, 35);
[viewDocumentButton addTarget:self action:#selector(openDocumentButtonPressedMethod:) forControlEvents:UIControlEventTouchDown];
[viewDocumentButton setTag:indexPath.row];
[cell.contentView addSubview:viewDocumentButton];
UIButton *downloadDocumentButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[downloadDocumentButton setTitle:#"Download Document" forState:UIControlStateNormal];
downloadDocumentButton.frame = CGRectMake(cellView.frame.origin.x + 5, viewDocumentButton.frame.origin.y + viewDocumentButton.frame.size.height + 5, 150, 35);
[downloadDocumentButton addTarget:self action:#selector(openDocumentButtonPressedMethod:) forControlEvents:UIControlEventTouchDown];
[downloadDocumentButton setTag:indexPath.row];
[cell.contentView addSubview:downloadDocumentButton];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
Additionally, you could...
- (IBAction)openDocumentButtonPressedMethod:(id)sender {
UIButton *button = (UIButton *)sender;
UIView *contentView = button.superview;
UITableViewCell *cell = (UITableViewCell *)contentView.superview;
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
// do something with the indexPath
}
And if you wanted to use the same method to handle both button events, then you could use the tag on the button to distinguish between the two buttons.
if (button.tag == 1) {
// do something with the indexPath view related
}
else {
// do something with the indexPath download related
}
Create a subclass of UIButton
#interface MyButton : UIButton
{ /* indexPath, other stuff */ }
#end
Then implement
- (void)sendAction:(SEL)action to:(id)target forEvent:(UIEvent *)event
to do something with the indexPath and other stuff before invoking the super for this method.
When you create the button, provide indexPath.
In your openDocumentButtonPressedMethod: method, do
CGPoint pointInTableView = [self.tableView convertPoint:sender.bounds.origin fromView:sender];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:pointInTableView];

Resources