iOS Button to Select All & Deselect All within UITableView

Experts,

How would you go about implementing an iOS Button to Select All and/or Deselect All for items within UITableView? Basically, my code below toggles the Checkmark Accessory state for each item. I want to implement buttons to select all/deselect all. I have created a button called SelectAll (with no code as I'm stuck). Thanks in advance!

namespace Sample
{
public partial class BusinessesViewController : UIViewController
{

    UITableView table;
    public BusinessesViewController (IntPtr handle) : base (handle)
    {

    }

    public override void ViewDidLoad ()
    {
        base.ViewDidLoad ();
        var width = View.Bounds.Width;
        var height = View.Bounds.Height;
        table = new UITableView(new CGRect(0, 100, width, height));
        table.AutoresizingMask = UIViewAutoresizing.All;
        CreateTableItems();
        Add (table);
    }

    protected void CreateTableItems ()
    {

        List<TableItem> tableItems = new List<TableItem> ();
        string documentsPath1 = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); 
        var localPath1 = Path.Combine(documentsPath1, "sample.json");
        var project = JsonConvert.DeserializeObject<RootObject> (System.IO.File.ReadAllText (localPath1));
        foreach (var business in project.Business) {
            //if (business.Latitude != 0 && business.Longitude != 0)
            tableItems.Add (new TableItem(business.Brief_Name_Location){SubHeading=business.Full_Address});
        }
        table.Source = new TableSource(tableItems, this);
    }

    partial void SelectAll_TouchUpInside (UIButton sender)
    {

        //throw new NotImplementedException ();
    }
}

public class TableSource : UITableViewSource {

    List<TableItem> tableItems;
    string cellIdentifier = "TableCell";
    BusinessesViewController owner;
    NSIndexPath checkedCell;
    UIButton selectAll;
    public TableSource (List<TableItem> items, BusinessesViewController owner)
    {
        tableItems = items;
        this.owner = owner;
    }


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

    public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
    {

        if (tableView.CellAt(indexPath).Accessory == UITableViewCellAccessory.Checkmark)
            tableView.CellAt(indexPath).Accessory = UITableViewCellAccessory.None;
        else
            tableView.CellAt(indexPath).Accessory = UITableViewCellAccessory.Checkmark;
        tableView.DeselectRow(indexPath, true);

    }


    public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
    {
        // request a recycled cell to save memory
        UITableViewCell cell = tableView.DequeueReusableCell (cellIdentifier);
        var cellStyle = UITableViewCellStyle.Subtitle;

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


        cell.TextLabel.Text = tableItems[indexPath.Row].Heading;

// if (cellStyle != UITableViewCellStyle.Value2)
// cell.ImageView.Image = UIImage.FromFile ("Images/" +tableItems[indexPath.Row].ImageName);

        return cell;
    }


}
public class TableItem {
    public string Heading { get; set; }

    public string SubHeading { get; set; }

    public string ImageName { get; set; }

    public UITableViewCellStyle CellStyle
    {
        get { return cellStyle; }
        set { cellStyle = value; }
    }
    protected UITableViewCellStyle cellStyle = UITableViewCellStyle.Default;

    public UITableViewCellAccessory CellAccessory
    {
        get { return cellAccessory; }
        set { cellAccessory = value; }
    }
    protected UITableViewCellAccessory cellAccessory = UITableViewCellAccessory.None;

    public TableItem () { }

    public TableItem (string heading)
    {  Heading = heading; }
}

}

Best Answer

Answers

  • ashalvaashalva GEMember ✭✭✭
    edited February 2016

    Hi @JimKOZLOWSKI ,

    1. Add these methods in your TableSource class.
      public void DeselectAll (UITableView tableView) { for (int i = 0; i < tableItems.Count; i++) { if (tableView.CellAt (NSIndexPath.FromRowSection ((nint)i, (nint)0)).Accessory == UITableViewCellAccessory.Checkmark) tableView.CellAt (NSIndexPath.FromRowSection ((nint)i, (nint)0)).Accessory = UITableViewCellAccessory.None; } } public void SelectAll (UITableView tableView) { for (int i = 0; i < tableItems.Count; i++) { if (tableView.CellAt (NSIndexPath.FromRowSection ((nint)i, (nint)0)).Accessory == UITableViewCellAccessory.None) tableView.CellAt (NSIndexPath.FromRowSection ((nint)i, (nint)0)).Accessory = UITableViewCellAccessory.Checkmark; } }
    2. I have created two buttons "select" and "desect" and subscribing it from ViewController.
      select.TouchUpInside += (sender, e) => { (table.Source as TableSource).SelectAll (table); }; deselect.TouchUpInside += (sender, e) => { (table.Source as TableSource).DeselectAll (table); };
  • JimKOZLOWSKIJimKOZLOWSKI USMember ✭✭

    Hi @ashalva,

    Thanks for taking the time to help!

    For some reason I'm getting a "NullReferenceException" at both "IF Statements":

    if (tableView.CellAt (NSIndexPath.FromRowSection ((nint)i, (nint)0)).Accessory == UITableViewCellAccessory.Checkmark)

    The code seems correct although. Wondering if you have any ideas. Thanks again!

  • ashalvaashalva GEMember ✭✭✭
    edited February 2016

    @JimKOZLOWSKI,

    Actually it is difficult to answer your question, why you are getting the NullReferenceException. Try setting the breakpoint and see what is null, tableView or tableView.CellAt (NSIndexPath.FromRowSection ((nint)i, (nint)0)).

  • JimKOZLOWSKIJimKOZLOWSKI USMember ✭✭
    edited February 2016

    Hi @ashalva,

    Thanks that was my first hunch to set a breakpoint at that location. This works for items <12 and below(which is the view of items before I scroll) I'm getting nulls after items >12 when I scroll down. Upon further investigation, I don't think my GetCell method is correct. I'm trying to preserve the state of the checkbox, but the cellIdentifier is reusing my cells, and I believe that is why I'm getting nulls. This is similar to https://forums.xamarin.com/discussion/22954/tableview-in-alertview-questions which was not solved. Is there anyway to preserve the state of the items when I scroll in GetCell? I understand for memory considerations, apple has decided to use this method. Again thanks for your expertise and support!!

Sign In or Register to comment.