The solution is probably very simple, but I couldn\'t just find it .. !
Working with storyboard (iOS 5), I have a tableViewController
, and a designed ST
Try to hide the cell before it is shown, in UITableViewDelegate
's tableView:willDisplayCell:forRowAtIndexPath: method. That's the final method where you can manipulate the cell's appearance. This however won't remove the space the cell should take, so another thing you can try is to set cell row's height to 0 using the tableView:heightForRowAtIndexPath: method of the same protocol.
Another method, which is most robust, is to devise a method for determining whether you need the date cell in the section and depending on the result, return the proper number of rows in the section, and return other section row cells taking the situation into account. And then reload tableView's data on viewWillAppear.
FYI (would comment if I could), if you are overriding a Grouped static UITableView from the Storyboard, then you'll also need to override the Header & Footer views & heights for each section you are modifying/hiding.
I also needed to set the return value for the "GetHeight" methods to something other than zero - implying that a zero value means something else (autolayout, or "not set" or the like).
The below code is in Xamarin iOS C#, but translates directly to the appropriate Obj-C methods:
public override void WillDisplayHeaderView(UITableView tableView, UIView headerView, nint section)
{
if (section == 0)
{
headerView = new UIView(new CGRect(0,0,0,0));
}
}
public override nfloat GetHeightForHeader(UITableView tableView, nint section)
{
if (section == 0)
{
return 1f;
}
return base.GetHeightForHeader(tableView, section);
}
public override void WillDisplayFooterView(UITableView tableView, UIView footerView, nint section)
{
if (section == 0)
{
footerView = new UIView(new CGRect(0, 0, 0, 0));
}
}
public override nfloat GetHeightForFooter(UITableView tableView, nint section)
{
if (section == 0)
{
return 1f;
}
return base.GetHeightForFooter(tableView, section);
}
Hopefully this is a bit more of a universal solution, but it's still not perfect
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
if (cell.hidden) {
return 0;
} else {
return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}
}
With this method you set your IBOutlet bound cell to be hidden, and then when the table tries to display a row, it first checks to see if the cell (using super call to get the cell) should be hidden, if so it returns a height of 0 which effectively removes it from the list. If the cell shouldn't be hidden then it gets the height from the super so whatever would normally happen still happens.
The only issue with this is that start and end cells are responsible for the divider at the top and bottom of the list or group. So if you hide the last cell in a group the bottom divider on the group will be inset slightly like it is on normal rows rather than full width. This is only a problem if you're hiding the top or bottom rows AND you are using a divider AND you care about totally standard display. The best solution in my case was simply to not hide the top or bottom rows. I moved any content that might be hidden to the middle of the group. Alternatively you could just accept that it isn't quite standard, or disable row dividers on your table.
// just authed with facebook, and I want to delete the first 3 rows of my 4 row table that are no longer necessary
- (NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section {
if(wantsFacebook)
return 1;
return 4;
}
After committing the updates, the tableView will call the numberOfRowsInSection delegate to get the updated number of rows and it MUST be the correct sum/difference between the rows when you started the insert/delete and the rows when you ended the insert/delete
Swift 3
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if indexPath.section == 0 {
cell.isHidden = true
}
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
if indexPath.section == 0 {
return 0
} else {
return super.tableView(tableView, heightForRowAt: indexPath)
}
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if(indexPath.section == 1) { //For example
return 0
}
}
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if(indexPath.section == 1) {
cell.hidden = true
}
}