Cross Platform
Android
iOS

Add a Cell Accessory

This recipe shows you how to set an accessory to display on the right side of a row.

Recipe

There are three accessory types:

Checkmark – displays a tick in the row.

DisclosureIndicator – displays a grey arrow, usually to indicate that another level of navigation will be displayed.

DetailDisclosureIndicator – displays a blue and white arrow, which is ‘clickable’ separately from the rest of the row.

These screenshots show the difference between them. The data and images shown below are included in the sample code.





To specify an accessory to be displayed in a cell:

  • Update the UITableViewCell constructor in the GetCell method to set the Accessory property of each cell (uncomment one of the values in this example):
public override UITableViewCell GetCell (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
{
    // request a recycled cell to save memory
    UITableViewCell cell = tableView.DequeueReusableCell (cellIdentifier);
    // if there are no cells to reuse, create a new one
    if (cell == null) {
        cell = new UITableViewCell (UITableViewCellStyle.Default, cellIdentifier);
    }

    cell.TextLabel.Text = tableItems[indexPath.Row];
    cell.Accessory = UITableViewCellAccessory.Checkmark;
    //cell.Accessory = UITableViewCellAccessory.DisclosureIndicator;
    //cell.Accessory = UITableViewCellAccessory.DetailDisclosureButton;
  
    // implement AccessoryButtonTapped
    //cell.Accessory = UITableViewCellAccessory.None; // to clear the accessory    
    return cell;
}
  • If using the DetailDisclosureIndicator, override the AccessoryButtonTapped method to provide some behavior when it is touched:
public override void AccessoryButtonTapped (UITableView tableView, NSIndexPath indexPath)
{
    new UIAlertView("DetailDisclosureButton Touched"
        , tableItems[indexPath.Row].Heading, null, "OK", null).Show();
}
  • Each row can have a different accessory (or none at all), however usually only the Checkmark is selectively displayed. Use the NSIndexPath parameter of GetCell to determine which row is being displayed and set the accessory accordingly.

Additional Information

The full source for the UITableViewSource subclass is shown here for reference:

public class TableSource : UITableViewSource {
    List<TableItem> tableItems;
     string cellIdentifier = "TableCell";

    public TableSource (List<TableItem> items)
    {
        tableItems = items;
    }

    public override int RowsInSection (UITableView tableview, int section)
    {
        return tableItems.Count;
    }

    public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
    {
        new UIAlertView("Row Selected"
            , tableItems[indexPath.Row].Heading, null, "OK", null).Show();
        tableView.DeselectRow (indexPath, true);
    }

    public override void AccessoryButtonTapped (UITableView tableView, NSIndexPath indexPath)
    {
        new UIAlertView("DetailDisclosureButton Touched"
            , tableItems[indexPath.Row].Heading, null, "OK", null).Show();
    }

    /// <summary>
    /// Called by the TableView to get the actual UITableViewCell to render for the particular row
    /// </summary>
    public override UITableViewCell GetCell (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
    {
        // request a recycled cell to save memory
        UITableViewCell cell = tableView.DequeueReusableCell (cellIdentifier);
        var cellStyle = UITableViewCellStyle.Default;
        // if there are no cells to reuse, create a new one

        if (cell == null) {
            cell = new UITableViewCell (cellStyle, cellIdentifier);
        }

        // UNCOMMENT one of these to see that accessory
        cell.Accessory = UITableViewCellAccessory.Checkmark;
        //cell.Accessory = UITableViewCellAccessory.DisclosureIndicator;
        //cell.Accessory = UITableViewCellAccessory.DetailDisclosureButton;
  
        // implement AccessoryButtonTapped
        //cell.Accessory = UITableViewCellAccessory.None; 

        // to clear the accessory
        cell.TextLabel.Text = tableItems[indexPath.Row].Heading;

        // Default style doesn't support Subtitle
        if (cellStyle == UITableViewCellStyle.Subtitle 
           || cellStyle == UITableViewCellStyle.Value1
           || cellStyle == UITableViewCellStyle.Value2) {
            cell.DetailTextLabel.Text = tableItems[indexPath.Row].SubHeading;
        }

        // Value2 style doesn't support an image
        if (cellStyle != UITableViewCellStyle.Value2)
            cell.ImageView.Image = UIImage.FromFile 
                ("Images/" +tableItems[indexPath.Row].ImageName);             
        return cell;
    }

}