1

I have a custom view with a UILabel and UIButton that I use for my grouped UITableView section headers like so:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    sectionHeaderView *headerView = [[sectionHeaderView alloc] initWithFrame:CGRectMake(0, 0, 320, 40)];
    [headerView.label setText:[[self tableView:tableView titleForHeaderInSection:section] uppercaseString]];

    if (_tableView.editing) 
        [headerView.button setHidden:NO];
    return headerView;
}

As you can see, I want to unhide the button when the UITableView is in editing mode.

I use a UITableView category method to return visibleHeaders so that I can refresh visible section header views without calling reloadData or reloadSections:withRowAnimation. That method basically returns an array of NSNumber objects and it works great.

Here is the method that sets UITableView in editing mode:

- (void)tapThatEditButtonBaby 
{
    [_tableView setEditing:YES animated:YES];
    for (NSNumber *sectionNumber in _tableView.visibleHeaders) {
        NSInteger section = [sectionNumber integerValue];
        sectionHeaderView *headerView = (sectionHeaderView *)[self tableView:_tableView viewForHeaderInSection:section];
        [headerView setBackgroundColor:[UIColor redColor]]; // highlighting view for testing.
    }
}

What would be a nice way of solving this one? Ideally, in my opinion, I'd like to be able to call something like updateSectionAndFooterAtIndex: from UITableView, but there isn't such exposed method... :(

JackyJohnson
  • 3,106
  • 3
  • 28
  • 35

2 Answers2

2

UPDATE

Sorry for prev answer, I didn't pay attention to that You have header for any section. So the solution for your situation it almost the same. You can just store NSDictionary with section index as key and buttons you're interested in for value. This dictionary will be filled in you - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section like that:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    //...
    [self.buttonsToHideInEditMode setObject:headerView.button forKey:@(section)];
}

and in your - (void)tapThatEditButtonBaby :

- (void)tapThatEditButtonBaby {
   ...
   [self.buttonsToHideInEditMode enumerateObjectsUsingBlock:^(UIButton *obj, NSUInteger idx, BOOL *stop) {
        obj.hidden = !_tableView.editing);
    }];
}

Prev answer

Actually you have two (or more :) ) basic options:

1) create separate method for creating header/footer view, like:

- (UIView *)tableHeaderView
{
    sectionHeaderView *headerView = [[sectionHeaderView alloc] initWithFrame:CGRectMake(0, 0, 320, 40)];
    [headerView.label setText:[[self tableView:tableView titleForHeaderInSection:section] uppercaseString]];

    if (_tableView.editing) 
        [headerView.button setHidden:NO];
    return headerView;
}
//same way for -(UIView *)tableFooterView;

Then any time You want to update/create header/footer just call:

_tableView.tableFooterView = [self tableFooterView];
//or
_tableView.tableHeaderView = [self tableHeaderView];

2) In Your situation if You want just change button according to editing state, You can just create property for your button and change it when You will need that.

in.disee
  • 1,102
  • 1
  • 7
  • 15
-1

Actually I found the mystery around my problem is that visual changes to section header view do not get updated if they are made to the view properties directly.

If I add this method setEditing:animated: in my sectionHeaderView:

- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
    if (animated) {
        [UIView animateWithDuration:0.25 animations:^{
            if (editing) {
                [label setFrame:CGRectMake(50, 15, 200, 20)];
                [button setFrame:CGRectMake(10, 12, 25, 25)];
            }
            else {
                [label setFrame:CGRectMake(15, 15, 200, 20)];
                [button setFrame:CGRectMake(-30, 12, 25, 25)];
            }
        }];
    }
}

Basically the below occurs in my tapThatEditButtonBaby method:

- (void)tapThatEditButtonBaby 
{
    [_tableView setEditing:YES animated:YES];
    for (NSNumber *sectionNumber in _tableView.visibleHeaders) {
        NSInteger section = [sectionNumber integerValue];
        sectionHeaderView *headerView = (sectionHeaderView *)[self tableView:_tableView viewForHeaderInSection:section];
        [sectionHeaderView setEditing:YES animated:YES];  // these visual changes work
        [sectionHeaderView.label setFrame:....]; // these changes don't...
    }
}

EDIT: UITableView automatically sends setEditing:animated to any subviews in its hierarchy that implements it. This is pretty useful knowledge. Basically I found that calling it in tapThatEditButtonBaby isn't needed at all.

JackyJohnson
  • 3,106
  • 3
  • 28
  • 35