panthor314 panthor314 - 2 months ago 25
iOS Question

Hiding cell in UITableView (in Xamarin)

I want to hide a cell based on whether or not it has any data for a particular user. My current approach causes an error

the requested operation resulted in a stack overflow
.

public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
...
cell.TextLabel.Text = items.Keys.ElementAt(indexPath.Row);
cell.DetailTextLabel.Text = items[items.Keys.ElementAt(indexPath.Row)];

if (string.IsNullOrEmpty(cell.DetailTextLabel.Text)){
cell.Hidden = true;
cell.Tag = 3;
}
return cell;
}

public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
{
UITableViewCell cell = tableView.CellAt(indexPath); //ERROR HERE
if (cell.Tag == 3)
{
return 0;
}
return base.GetHeightForRow(tableView, indexPath);
}


How can I avoid this error and properly hide a row?

Answer

My guess is that GetCell() calls GetHeightForRow() which calls GetCell() which calls GetHeightForRow()...that's where your stack overflow is coming from.

You should not use the visual representation (= the cell) to determine whether a row should be visible or not. Your (data) model should be responsible for this. In other words: whatever object type your items dictionary contains (maybe it's of type Person - I don't know), it should have a property IsVisible or something similar. Then in GetHeightForRow() you access the item and inspect the property and decide what the row height will be and return 0 for an invisible row.

By the way: I'm not aware of the context of your code above (*), but in general you should not call base.GetHeightForRow(). The method natively is part of a delegate which is implemented as an ObjectiveC protocol. This means, there is no base.

(*) If you derive from UITableViewSource or UITableViewDataSource there's no side effects when calling base but if you implement the methods directly in a UITableViewController you might see a You_Should_Not_Call_Base_Exception.

Comments