How can I update/reload/refresh a section header view in a UITableView?

后端 未结 2 2303
故里飘歌
故里飘歌 2021-02-20 16:29

I\'m willing to change a specific header view of my UITableView when I click a row.

I\'ve read all posts about it yet. I tried \"reloadData\", \"setNeed

相关标签:
2条回答
  • 2021-02-20 17:23

    Have you tried reloadRowsAtIndexPaths:withRowAnimation: where you set the row property of the NSIndexPath passed in as NSNotFound? So reloading just the header of section 3, for instance would look like

    NSIndexPath * headerIndexPath = [NSIndexPath indexPathForRow: NSNotFound section:3];
    [self.tableView reloadRowsAtIndexPaths:@[headerIndexPath] withRowAnimation: UITableViewRowAnimationAutomatic];
    

    I guarantee nothing, but I'm pretty sure it used to work before, because I used it a couple of times.

    But even if it works, it's still a hack that might get broken by Apple any time.

    edit

    Ok, never mind. I tried this with iOS 7 in Xcode 5 and for some reason, even with NSNotFound as the row number, it still reloads the whole sections (with all its cells). So this does not work any more, damn.

    0 讨论(0)
  • 2021-02-20 17:27

    You just change it directly. I created an instance variable in the header file for a label that I will put in the header's view I'll create:

    @interface MainViewController : UITableViewController {
        // creating my datasource array instance variable
        NSArray *_items;
    
        // this is the label I will add to the header view when I create it
        UILabel *_headerLabel;
    }
    
    @end
    

    And in my tableView when they select a row I call a function that simply changes the text on the label:

    @implementation MainViewController
    
    - (id)init {
        self = [super initWithStyle:UITableViewStyleGrouped];
    
        / filling my datasource with test strings
        _items = @[@"one", @"two"];
    
        return self;
    }
    
    - (void)changeHeaderLabel:(NSString *)newLabel {
        // when this function gets called and is passed a string, I will simply
        // set the text on the label to the new string and viola!
        _headerLabel.text = newLabel;
    }
    
    #pragma mark - Table view data source
    
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
        // this table will only have a single section for demo purposes
        return 1;
    }
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        // return the count of my datasource array
        return _items.count;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        // attempt to create a cell by reusing one with a given identifier
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    
        // if I wasn't able to reuse one
        if (cell == nil) {
            // create one from scratch with that identifier
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
        }
    
        // now simply set the text on the cell from my data source array of strings
        cell.textLabel.text = _items[indexPath.row];
    
        // and return the cell
        return cell;
    }
    
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
        // deselect the row so the cell automatically fades out after selection
        [tableView deselectRowAtIndexPath:indexPath animated:YES];
    
        // here you could do one of two things, either get a reference to the cell itself,
        // and then get the value stored in it's textLabel
        UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
        NSString *newHeaderTitleString = selectedCell.textLabel.text;
    
        // OR you can get it right from your datasource
        NSString *newHeaderTitleString = _items[indexPath.row];
    
        // then just call the above function with the string as the single param
        [self changeHeaderLabel:newHeaderTitleString];
    }
    
    - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
        // here I just create a view that will span the whole frame and is an arbitrary height
        UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 80)];
        // set the background color to clear
        headerView.backgroundColor = [UIColor clearColor];
    
        // then I initialize my instance variable with a frame that's centered in the view
        // for aesthetic purposes
        _headerLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, self.view.frame.size.width - 10, 80)];
    
        // then I set the text color, add an autoresizing mask so if the view rotates
        // it still remains centered properly, set the text to some starting value, 
        // and add it to the headerView I previously created
        _headerLabel.textColor = [UIColor darkGrayColor];
        _headerLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth;
        _headerLabel.text = @"Before";
        [headerView addSubview:_headerLabel];
    
        // then I return the headerView
        return headerView;
    }
    
    - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
        // return an arbitrary height here for testing
        return 80;
    }
    

    That results in the following:

    enter image description here

    enter image description here enter image description here

    If you have any questions let me know! This is just a quick example to demonstrate it, but you may want to customize the view in a different way altogether. This should at least solve your problem and give you a starting point to work from.

    0 讨论(0)
提交回复
热议问题