user1898829
user1898829

Reputation: 3527

How can I make button in section header for uitableview stay selected

I have a button that I want to change the background image if its selected. The code I have here works but if I scroll up and down again it becomes unselected.

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    UIView *sectionHeader = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, 33)];
    UILabel *sectionHeaderLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 100, 30)];
    sectionHeaderLabel.text = [NSString stringWithFormat:@"Section %i",section+1];
    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(200, 5, 42, 20)];
    [button setBackgroundImage:[UIImage imageNamed:@"unselected_image"] forState:UIControlStateNormal];
    [button setBackgroundImage:[UIImage imageNamed:@"selected_image"] forState:UIControlStateSelected];
    [button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
    [sectionHeader addSubview:button];
    return sectionHeader;
}

- (void)buttonPressed:(id)sender {
    UIButton *allButton = (UIButton*)sender;
    allButton.selected = !allButton.selected;
}

Upvotes: 2

Views: 1748

Answers (3)

Ty Lertwichaiworawit
Ty Lertwichaiworawit

Reputation: 2950

1) Create an image name array in you ViewDidLoad. This array tracks the name of you photos whether if its been clicked or not.

- (void)viewDidLoad
{
    //this array is just an example, loop and add items to the array for the number of sections you want
    //in this example there are 5 sections with 5 images
    imageNameArray = [[NSMutableArray alloc] initWithObjects:@"unselected_image", @"unselected_image", @"unselected_image", @"unselected_image", @"unselected_image", nil];
}

2) Your viewForHeaderInSection

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    UIView *sectionHeader = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, 33)];
    UILabel *sectionHeaderLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 100, 30)];
    sectionHeaderLabel.text = [NSString stringWithFormat:@"Section %i",section+1];
    button = [[UIButton alloc] initWithFrame:CGRectMake(200, 5, 42, 20)];
    [button setBackgroundImage:[UIImage imageNamed:[imageNameArray objectAtIndex:section]] forState:UIControlStateNormal];
    [button setTag:section];
    [button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
    [sectionHeader addSubview:button];
    return sectionHeader;
}

3) If button is pressed change the name of you image in the Array

- (void)buttonPressed:(id)sender
{
    UIButton *allButton = (UIButton*)sender;

    [imageNameArray insertObject:@"selected_image" atIndex:[allButton tag]];
    [allButton setBackgroundImage:[UIImage imageNamed:[imageNameArray objectAtIndex:[allButton tag]]] forState:UIControlStateNormal];
}

Upvotes: 4

Rajesh
Rajesh

Reputation: 960

That happen because when table scroll up and down it will again create cell so you have to manage it in some way which button is selected or not and again set selected state to those button which are previously selected in viewForHeaderInSection you can do that as bellow

//Define in header file
NSMutableArray *mutArrSelected;

//Initlise in viewdidload
mutArrSelected = [[NSMutableArray alloc] init];


- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{

    if(mutArrSelected.count < section)
    {
        [mutArrSelected addObject:[NSNumber numberWithBool:NO]];
    }

    UIView *sectionHeader = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, 33)];
    UILabel *sectionHeaderLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 100, 30)];
    sectionHeaderLabel.text = [NSString stringWithFormat:@"Section %i",section+1];
    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(200, 5, 42, 20)];
    if([[mutArrSelected objectAtIndex:section] boolValue])
    {
        button.selected = YES;
    }
    button.tag = section;
    [button setBackgroundImage:[UIImage imageNamed:@"unselected_image"] forState:UIControlStateNormal];
    [button setBackgroundImage:[UIImage imageNamed:@"selected_image"] forState:UIControlStateSelected];
    [button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
    [sectionHeader addSubview:button];
    return sectionHeader;
}

- (void)buttonPressed:(id)sender
{
    UIButton *allButton = (UIButton*)sender;
    allButton.selected = !allButton.selected;

    [mutArrSelected removeObjectAtIndex:allButton.tag];
    [mutArrSelected insertObject:[NSNumber numberWithBool:allButton.selected] atIndex:allButton.tag];
}

Upvotes: 1

Jesper Schl&#228;ger
Jesper Schl&#228;ger

Reputation: 375

What happens here is that every time the view becomes visible, you actually create a completely new view with everything reset. Instead of doing that you could simply save the view and re-use the same view every time. Create the view in viewDidLoad instead:

- (void)viewDidLoad
{
    sectionHeader = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.frame.size.width, 33)];
    UILabel *sectionHeaderLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 100, 30)];
    sectionHeaderLabel.text = [NSString stringWithFormat:@"Section %i",section+1];
    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(200, 5, 42, 20)];
    [button setBackgroundImage:[UIImage imageNamed:@"unselected_image"] forState:UIControlStateNormal];
    [button setBackgroundImage:[UIImage imageNamed:@"selected_image"] forState:UIControlStateSelected];
    [button addTarget:self action:@selector(buttonPressed:) forControlEvents:UIControlEventTouchUpInside];
    [sectionHeader addSubview:button];
}

viewForHeaderInSection simply becomes:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    return sectionHeader;
}

Please note that if you have more than one section you would need to create an array of section header views and return the correct one for each section, based on the value of the section in viewForHeaderInSection

Upvotes: 1

Related Questions