locked
Custom UITableViewCell not showing edit mode buttons RRS feed

  • Question

  • User8355 posted

    Hi,

    I've got an UITableView with custom UITableViewCells and I'm trying to show the edit mode buttons to allow users to delete rows. However, the cells are shown without any edit buttons like this:

    I've followed the xamarin's "Tableview and cells" tutorials without result.

    In my viewController I create the table source and pass it to the table view:

        //tableItems is a List of custom cell items
    TableSourceCellMenuItem tableSource = new TableSourceCellMenuItem(tableItems, this);
    TableViewReceptesDelMomentSeleccionat.SetEditing(true, true);
    TableViewReceptesDelMomentSeleccionat.Source = tableSource;
    

    I've also made an override of some methods in my TableSourceCellMenuItem class wich is a subclass of UITableViewSource:

        public override void CommitEditingStyle (UITableView tableView, UITableViewCellEditingStyle editingStyle, MonoTouch.Foundation.NSIndexPath indexPath)
        {
            switch (editingStyle) {
            case UITableViewCellEditingStyle.Delete:
                // remove the item from the underlying data source
                tableItems.RemoveAt(indexPath.Row);
                // delete the row from the table
                tableView.DeleteRows (new NSIndexPath[] { indexPath }, UITableViewRowAnimation.Fade);
                break;
            default:
                break;
            }
        }
    
        public override bool CanEditRow (UITableView tableView, NSIndexPath indexPath)
        {
            return true; // return false if you wish to disable editing for a specific indexPath or for all rows
        }
    
        public override bool CanMoveRow (UITableView tableView, NSIndexPath indexPath)
        {
            return false; // return false if you don't allow re-ordering
        }
    
        public override UITableViewCellEditingStyle EditingStyleForRow (UITableView tableView, NSIndexPath indexPath)
        {
            return UITableViewCellEditingStyle.Delete; // this example doesn't support Insert
        }
    

    Could anyone help me to find out what is going wrong with this code? I would be so pleased if you help me. Thanks in advance.

    Monday, April 29, 2013 2:59 PM

Answers

  • User37696 posted

    @RogierKoning

    Ok, so I took your exact code and put it in a project. The problem lies within your implementation of a UITableViewCell in the class CellMenuItem. Because you made your own cell, I think it removes the default behavior of what happens when editing.

    There may be a way to get this to work, but I couldnt get it quickly. In order to get the results you want, I removed the CellMenuItem class because you dont need it. You were only doing something very simple, so using a pre-defined cell type will work fine. In the TableSOurceCellMenuItem class you can do this instead (I commented out what you had before).

    public override UITableViewCell GetCell (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
    {
    //  CellMenuItem cell = tableView.DequeueReusableCell (cellIdentifier) as CellMenuItem;
    //  if (cell == null)
    //  cell = new CellMenuItem (cellIdentifier);
    //  cell.UpdateCell (tableItems[indexPath.Row].Heading, tableItems[indexPath.Row].SubHeading, tableItems[indexPath.Row].Image);
    //          
    //  cell.Accessory = UITableViewCellAccessory.DisclosureIndicator;
    
        var cell = tableView.DequeueReusableCell(cellIdentifier);
        if(cell == null)
            cell = new UITableViewCell(UITableViewCellStyle.Subtitle, cellIdentifier);
    
        cell.TextLabel.Text = tableItems[indexPath.Row].Heading;
        cell.DetailTextLabel.Text = tableItems[indexPath.Row].SubHeading;
        cell.ImageView.Image = tableItems[indexPath.Row].Image;
        cell.Accessory = UITableViewCellAccessory.DisclosureIndicator;
    
        return cell;
    }
    

    If this wont work for you and you will need to make your own cell for whatever reason let me know. I will try and see how to get that to work.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Thursday, May 2, 2013 4:01 PM

All replies

  • User37696 posted

    I just want to make sure I understand the above. You said:

    I've also made an override of some methods in my custom cell:

    Did you mean that this code is your implementation of a custom cell, in a class like:

    public class MyCell : UITableViewCell
    

    Or did you mean that its in your UITableViewSource class. This code that you wrote:

        public override void CommitEditingStyle (UITableView tableView, UITableViewCellEditingStyle editingStyle, MonoTouch.Foundation.NSIndexPath indexPath)
        {
            switch (editingStyle) {
            case UITableViewCellEditingStyle.Delete:
                // remove the item from the underlying data source
                tableItems.RemoveAt(indexPath.Row);
                // delete the row from the table
                tableView.DeleteRows (new NSIndexPath[] { indexPath }, UITableViewRowAnimation.Fade);
                break;
            default:
                break;
            }
        }
    
        public override bool CanEditRow (UITableView tableView, NSIndexPath indexPath)
        {
            return true; // return false if you wish to disable editing for a specific indexPath or for all rows
        }
    
        public override bool CanMoveRow (UITableView tableView, NSIndexPath indexPath)
        {
            return false; // return false if you don't allow re-ordering
        }
    
        public override UITableViewCellEditingStyle EditingStyleForRow (UITableView tableView, NSIndexPath indexPath)
        {
            return UITableViewCellEditingStyle.Delete; // this example doesn't support Insert
        }
    

    Should be in your TableSourceCellMenuItem class that you implemented; is it in that class?

    Monday, April 29, 2013 3:11 PM
  • User8355 posted

    Thank you @John for your quick response.

    I'm sorry, I was wrong. This code is from a subclass of UITableViewSource.

    public class TableSourceCellMenuItem: UITableViewSource {

    ...

    public override void CommitEditingStyle(...){...}

    ...

    public override bool CanEditRow (...){...}

    ... }

    I've corrected it in the question.

    Monday, April 29, 2013 3:33 PM
  • User37696 posted

    @RogierKoning

    I believe that code is suppose to go in your TableSourceCellMenuItem class, not your CellMenuItem class.

    Monday, April 29, 2013 3:36 PM
  • User8355 posted

    I'm still having the same problem. I haven't found how to solve it. Does anyone managed with this issue before and got over it?

    Thursday, May 2, 2013 7:21 AM
  • User37696 posted

    @RogierKoning Yes I have implemented this successfully. Can you post some example code of what you are doing? It would seem something you are doing is incorrect somewhere in the pipeline...

    Thursday, May 2, 2013 12:27 PM
  • User8355 posted

    Thank you @John for your response.

    In my viewController I create the cells and make up the tablesource like this:

    List<CellMenuItem> tableItems = new List<CellMenuItem>();
    
    CellMenuItem cell1 = new CellMenuItem(new NSString("Spagheti bolognese"));
    cell1.Heading = "Spaghetti bolognese";
    cell1.Image = UIImage.FromFile("cellImage1.png");
    tableItems.Add(cell1);
    
    CellMenuItem cell2 = new CellMenuItem(new NSString("Groene Salade"));
    cell2.Heading = "Groene Salade";        
    cell2.Image = UIImage.FromFile("cellImage2.png");
    tableItems.Add(cell2);
    
    TableSourceCellMenuItem tableSource = new TableSourceCellMenuItem(tableItems, this);
    TableViewReceptesDelMomentSeleccionat.Source = tableSource;
    TableViewReceptesDelMomentSeleccionat.SetEditing(true, true);
    

    And I've created a subclass of UITableViewCell called CellMenuItem like this:

    public class CellMenuItem: UITableViewCell
    {
    
    UILabel headingLabel, subheadingLabel;
    UIImageView imageView;
    
    public CellMenuItem (NSString cellId) : base (UITableViewCellStyle.Default, cellId)
        {
            imageView = new UIImageView();
            headingLabel = new UILabel () {
                Font = UIFont.FromName("Cochin-BoldItalic", 22f),
                TextColor = UIColor.FromRGB (127, 51, 0),
                BackgroundColor = UIColor.Clear
            };
            subheadingLabel = new UILabel () {
                Font = UIFont.FromName("AmericanTypewriter", 12f),
                TextColor = UIColor.FromRGB (38, 127, 0),
                TextAlignment = UITextAlignment.Center,
                BackgroundColor = UIColor.Clear
            };
            ContentView.Add (headingLabel);
            ContentView.Add (subheadingLabel);
            ContentView.Add (imageView);
        }
    
    public void UpdateCell (string caption, string subtitle, UIImage image){
        imageView.Image = image;
        headingLabel.Text = caption;
        subheadingLabel.Text = subtitle;
    }
    
    public override void LayoutSubviews (){
    
        imageView.Frame = new RectangleF(ContentView.Bounds.Location, new Size(80, 54));
    
        headingLabel.Frame = new RectangleF(imageView.Frame.Width + 10, 0, ContentView.Bounds.Width - imageView.Frame.Width - 10, imageView.Frame.Height);
    
    }
    
    
    public override void WillTransitionToState (UITableViewCellState state)
        {base.WillTransitionToState (state);}
    
    public string Heading {
            get{ return headingLabel.Text; }
            set{ headingLabel.Text = value; }
    }
    
    public string SubHeading {
            get{ return subheadingLabel.Text; }
            set{ subheadingLabel.Text = value; }
    }
    
    
    public UIImage Image {
            get{ return imageView.Image; }
            set{ imageView.Image = value; }
    }
    
    }
    

    And my TableSourceCellMenuItem which is a subclass of UITableViewSource is like the code posted in my question.

    I think the problem must be a small think, but I can't manage to found it. If you could help me to found where the problem is, I'd be so pleased.

    Thursday, May 2, 2013 2:34 PM
  • User37696 posted

    @RogierKoning Thank you for posting the code, but can you also post your TableSourceCellMenuItem? I know you said it is like the code posted in the question, but that code is not there. I would like to see what you are doing in the TableSourceCellMenuItem.

    Thanks!

    Thursday, May 2, 2013 2:47 PM
  • User8355 posted

    @John thank you for your interest.

    The code of my tableViewSource class is:

    public class TableSourceCellMenuItem: UITableViewSource
    {
        List<CellMenuItem> tableItems = new List<CellMenuItem>();
        NSString cellIdentifier = new NSString("TableCell");
        UIViewController viewControllerEnPantalla;
    
        public TableSourceCellMenuItem (List<CellMenuItem> items, UIViewController viewControllerEnPantalla)
        {
            tableItems = items;
            this.viewControllerEnPantalla = viewControllerEnPantalla;
        }
    
        public override int RowsInSection (UITableView tableview, int section)
        {
            return tableItems.Count;
        }
    
    
        public override UITableViewCell GetCell (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
        {
            CellMenuItem cell = tableView.DequeueReusableCell (cellIdentifier) as CellMenuItem;
            if (cell == null)
                cell = new CellMenuItem (cellIdentifier);
            cell.UpdateCell (tableItems[indexPath.Row].Heading, tableItems[indexPath.Row].SubHeading, tableItems[indexPath.Row].Image);
    
            cell.Accessory = UITableViewCellAccessory.DisclosureIndicator;
    
            return cell;
        }
    
        public override void CommitEditingStyle (UITableView tableView, UITableViewCellEditingStyle editingStyle, MonoTouch.Foundation.NSIndexPath indexPath)
        {
            switch (editingStyle) {
            case UITableViewCellEditingStyle.Delete:
                // remove the item from the underlying data source
                tableItems.RemoveAt(indexPath.Row);
                // delete the row from the table
                tableView.DeleteRows (new NSIndexPath[] { indexPath }, UITableViewRowAnimation.Fade);
                break;
            default:
                break;
            }
        }
    
        public override bool CanEditRow (UITableView tableView, NSIndexPath indexPath)
        {
            return true; // return false if you wish to disable editing for a specific indexPath or for all rows
        }
    
        public override bool CanMoveRow (UITableView tableView, NSIndexPath indexPath)
        {
            return false; // return false if you don't allow re-ordering
        }
    
        public override UITableViewCellEditingStyle EditingStyleForRow (UITableView tableView, NSIndexPath indexPath)
        {
            return UITableViewCellEditingStyle.Delete; // this example doesn't support Insert
        }
    
    
        public override void RowSelected (UITableView tableView, NSIndexPath indexPath)
        {
            tableView.DeselectRow (indexPath, true); // normal iOS behaviour is to remove the blue highlight
        }
    
    }
    
    Thursday, May 2, 2013 2:55 PM
  • User37696 posted

    @RogierKoning

    Ok, so I took your exact code and put it in a project. The problem lies within your implementation of a UITableViewCell in the class CellMenuItem. Because you made your own cell, I think it removes the default behavior of what happens when editing.

    There may be a way to get this to work, but I couldnt get it quickly. In order to get the results you want, I removed the CellMenuItem class because you dont need it. You were only doing something very simple, so using a pre-defined cell type will work fine. In the TableSOurceCellMenuItem class you can do this instead (I commented out what you had before).

    public override UITableViewCell GetCell (UITableView tableView, MonoTouch.Foundation.NSIndexPath indexPath)
    {
    //  CellMenuItem cell = tableView.DequeueReusableCell (cellIdentifier) as CellMenuItem;
    //  if (cell == null)
    //  cell = new CellMenuItem (cellIdentifier);
    //  cell.UpdateCell (tableItems[indexPath.Row].Heading, tableItems[indexPath.Row].SubHeading, tableItems[indexPath.Row].Image);
    //          
    //  cell.Accessory = UITableViewCellAccessory.DisclosureIndicator;
    
        var cell = tableView.DequeueReusableCell(cellIdentifier);
        if(cell == null)
            cell = new UITableViewCell(UITableViewCellStyle.Subtitle, cellIdentifier);
    
        cell.TextLabel.Text = tableItems[indexPath.Row].Heading;
        cell.DetailTextLabel.Text = tableItems[indexPath.Row].SubHeading;
        cell.ImageView.Image = tableItems[indexPath.Row].Image;
        cell.Accessory = UITableViewCellAccessory.DisclosureIndicator;
    
        return cell;
    }
    

    If this wont work for you and you will need to make your own cell for whatever reason let me know. I will try and see how to get that to work.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Thursday, May 2, 2013 4:01 PM
  • User8355 posted

    @John thank you for your response. It works!! But the image is naturally shown by the default size.

    I only want the image of each cell to be wider, because I need to show images in 16:9 format. Is there any possibility of modifying the width of the imageview without creating my own UITableViewCell?

    Thursday, May 2, 2013 4:20 PM
  • User8355 posted

    Finally I've found the solution.

    I was missing the line:

    base.LayoutSubviews ();

    in the overriden method LayoutSubviews of my custom UITableViewCell.

    Thank you so much @John for indicating me that the problem was on my custom UITableViewCell.

    Friday, May 3, 2013 9:31 AM
  • User37696 posted

    @RogierKoning Good Find! Glad I could help in some way.

    Friday, May 3, 2013 12:20 PM