LDK
LDK

Reputation: 2575

Add button to UITableViewCell's Accessory View

Goal: when a user selects a cell, a button is added to that cell. Within my didSelectRowAtIndexPath function I have the following:

UIButton *downloadButton = [[UIButton alloc] init];
downloadButton.titleLabel.text = @"Download";
[downloadButton setFrame:CGRectMake(40, 0, 100, 20)];
[[self.tableView cellForRowAtIndexPath:indexPath].accessoryView addSubview:downloadButton];
[[self.tableView cellForRowAtIndexPath:indexPath].accessoryView setNeedsLayout];

[downloadButton release];

Unfortunately that doesn't seem to do anything. Am I redrawing the cell correction? Do I need to add it another way?

Upvotes: 20

Views: 35820

Answers (10)

Furkan
Furkan

Reputation: 306

Swift 4 and above: Add button to UITableViewCell's Accessory View

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        let cell = Table.dequeueReusableCell(withIdentifier: "identifier", for: indexPath)

            let accessoryButton = UIButton(type: .custom)
            accessoryButton.addTarget(self, action: #selector(deleteCell(sender:)), for: .touchUpInside)
            accessoryButton.setImage("Add_image", for: .normal) 
            accessoryButton.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
            accessoryButton.contentMode = .scaleAspectFit

            cell.accessoryView = accessoryButton as UIView

            return cell
    }

Add Selector Method

    func deleteCell(sender: AnyObject)
    {
        let pointInTable: CGPoint = sender.convert(sender.bounds.origin, to: self.Table)
        let cellIndexPath = self.Table.indexPathForRow(at: pointInTable)
        let point = cellIndexPath!.row

    }

Upvotes: 4

Vyacheslav
Vyacheslav

Reputation: 27221

let button = UIButton(type:.roundedRect)
button.setTitle("A", for: .normal)
button.sizeToFit()
cell.accessoryView = button

Upvotes: 2

user4919266
user4919266

Reputation:

use this :

cell.accessoryType=UITableViewCellAccessoryDetailDisclosureButton;

Upvotes: 0

user1107173
user1107173

Reputation: 10784

Swift

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! UITableViewCell
    let accessoryButton = UIButton.buttonWithType(UIButtonType.ContactAdd) as! UIButton
    cell.accessoryView = accessoryButton

    return cell
}

Upvotes: 0

Senseful
Senseful

Reputation: 91911

I had the same problem. Attempting to set the accessoryView to a UIButton which had an image caused it to not appear.

The trick was to call [UIButton sizeToFit], to ensure its frame is set properly.

Upvotes: 14

mdebeus
mdebeus

Reputation: 1928

Here is my example for a the full solution to your request:

In my UITableViewCell subclass (I call it RNWNewItemCell):

-(void)configureCell...
{
   // create the button
   self.btnSeekDuplicate = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 22, 22)];
   // just make it yellow until we get our real image..
   self.btnSeekDuplicate.backgroundColor = [UIColor yellowColor];
   // add the handler for the button press
   [self.btnSeekDuplicate addTarget:self
                             action:@selector(seekDuplicateButtonWasPressed) 
                   forControlEvents:UIControlEventTouchUpInside];
   // make it visible in the table cell...
   [self setAccessoryView:self.btnSeekDuplicate];
}

- (void)seekDuplicateButtonWasPressed
{
    do something...
}

In my Table Code that uses the cell...

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
   ...
   RNWNewItemCell *aNewItemCell = [tableView dequeueReusableCellWithIdentifier:cellIdentifierForNewItemCell forIndexPath:indexPath];
   [aNewItemCell configureCell...]
   ...
}

Note that accessoryButtonTappedForRowWithIndexPath is NOT called when you set the table cell's accessoryView. Probably because they assume you are using a view that responds to events.

Upvotes: 1

BP.
BP.

Reputation: 10083

Try this block of code instead of the block you provided above:

UIButton *downloadButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[downloadButton setTitle:@"Download" forState:UIControlStateNormal];
[downloadButton setFrame:CGRectMake(0, 0, 100, 35)];
[tableView cellForRowAtIndexPath:indexPath].accessoryView = downloadButton;

This should display the button, but you will still need to hook up some kind of selector to it using addTarget. (I am not sure if listening in for the accessoryButtonTappedForRowWithIndexPath delegate will work in this case, try that first and see if it fires on your button press.)

Upvotes: 23

Rick
Rick

Reputation: 1215

Its always best to add any views that you are adding to a cell to cell.contentView. Also try to check if the accessoryView is nil.

Upvotes: 0

progrmr
progrmr

Reputation: 77291

Assign the button as the accessory view rather than a subview of the accessory view.

UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryView = downloadButton;

Upvotes: 8

Ecarrion
Ecarrion

Reputation: 4950

Try This:

[[self.tableView cellForRowAtIndexPath:indexPath].contentView addSubview:downloadButton];

And remember to delete that button when the cell is being reused.

Upvotes: 1

Related Questions