سؤال

In my tableview each cell gets a subview by didselectRowAtIndexPath to highlight the current selected row. Everything works fine but in the moment when the tableview was scrolled the subview won't hide from a cell which was selected before.

In short: How do you would make a replacement for "Managing Cell Selection and Highlighting"?

Thanks in advance!

Here is my code:

#import "ViewController.h"

@interface ViewController () <UITableViewDataSource, UITableViewDelegate>

@property (nonatomic,strong) NSArray *tableData;

@end

@implementation ViewController

@synthesize checked_icon;

- (void)viewDidLoad {

    [super viewDidLoad];

    self.tableData = @[@"A",@"B",@"C",@"D",@"E",@"F",@"G",@"H",@"I",@"J",@"K",@"L",@"M",@"N",@"O",@"P",@"Q",@"R",@"S",@"T"];

}

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];
}



- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [self.tableData count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

        checked_icon = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 44)];
        checked_icon.backgroundColor =[UIColor redColor];
    }

    cell.textLabel.text = self.tableData[indexPath.row];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    return cell;
}


- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    NSIndexPath *currentSelectedIndexPath = [tableView indexPathForSelectedRow];
    if (currentSelectedIndexPath != nil)
    {
        [[tableView cellForRowAtIndexPath:currentSelectedIndexPath] setBackgroundColor: [UIColor whiteColor]];

        UITableViewCell *cell = [tableView cellForRowAtIndexPath:currentSelectedIndexPath];

        if (cell.isSelected == YES) {
            checked_icon.backgroundColor = [UIColor redColor];
        }
        else {
            checked_icon.backgroundColor = [UIColor clearColor];
        }
    }

    return indexPath;
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    [[tableView cellForRowAtIndexPath:indexPath] setBackgroundColor:[UIColor lightGrayColor]];
    UITableViewCell *selectedcell = [tableView cellForRowAtIndexPath:indexPath];
    [selectedcell.contentView addSubview:checked_icon];

}


- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {

    if (cell.isSelected == YES) {
        [cell setBackgroundColor:[UIColor lightGrayColor]];

    }

    else {
        [cell setBackgroundColor:[UIColor whiteColor]];
    }
}

@end
هل كانت مفيدة؟

المحلول

You should use 'selectedBackgroundView' property of UITableViewCell, as selection will be handled for you.

EDIT

The proper way to do this would be to create a subclass of UITableViewCell and have a reference to your checkmark in there.

While the code from my original post will work, it's not the best way to do it and will quickly get complicated if your cell view gets more complex.

ORIGINAL

If you don't want to use 'selectedBackgroundView', then this should probably solve your problem:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

        UIView *checked_icon = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 44)];
        checked_icon.tag = 1234;
        [cell.contentView addSubview:checked_icon];
    }

    UIView *checked_icon = [cell.contentView viewWithTag:1234];
    // Note: color should be set each time a cell is presented
    if (cell.isSelected) {
        checked_icon.backgroundColor = [UIColor redColor];
    }
    else {
        checked_icon.backgroundColor = [UIColor clearColor];
    }

    cell.textLabel.text = self.tableData[indexPath.row];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    return cell;
}

نصائح أخرى

Thanks to MrNickBarker!

viewWithTag seems to be the one and only solution...

Here is the code: (not perfect but it works)

#import "ViewController.h"

@interface ViewController () <UITableViewDataSource, UITableViewDelegate>

@property (nonatomic,strong) NSArray *tableData;

@end

@implementation ViewController

@synthesize checked_icon;

- (void)viewDidLoad {

    [super viewDidLoad];

    self.tableData = @[@"A",@"B",@"C",@"D",@"E",@"F",@"G",@"H",@"I",@"J",@"K",@"L",@"M",@"N",@"O",@"P",@"Q",@"R",@"S",@"T"];

}

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];
}


- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [self.tableData count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSString *CellIdentifier = [NSString stringWithFormat:@"cell-%d",indexPath.row];
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

        checked_icon = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 10, 44)];
        checked_icon.tag = 1234;
        [cell.contentView addSubview:checked_icon];
    }

    cell.textLabel.text = self.tableData[indexPath.row];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;

    return cell;
}


- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    NSIndexPath *currentSelectedIndexPath = [tableView indexPathForSelectedRow];
    if (currentSelectedIndexPath != nil) {

        [[tableView cellForRowAtIndexPath:currentSelectedIndexPath] setBackgroundColor: [UIColor whiteColor]];
        UITableViewCell *selectedcell = [tableView cellForRowAtIndexPath:currentSelectedIndexPath];

        checked_icon = [selectedcell.contentView viewWithTag:1234];

        if (selectedcell.isSelected == YES) {
            checked_icon.backgroundColor = [UIColor redColor];
        }
        else {
            checked_icon.backgroundColor = [UIColor clearColor];
        }
    }

    checked_icon.backgroundColor = [UIColor clearColor];

    return indexPath;
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    [[tableView cellForRowAtIndexPath:indexPath] setBackgroundColor:[UIColor lightGrayColor]];
    UITableViewCell *selectedcell = [tableView cellForRowAtIndexPath:indexPath];

    checked_icon = [selectedcell.contentView viewWithTag:1234];

    if (selectedcell.isSelected == YES) {
        NSLog(@"redColor");
        checked_icon.backgroundColor = [UIColor clearColor];
    }
    else {
        NSLog(@"clearColor");
        checked_icon.backgroundColor = [UIColor clearColor];
    }

    checked_icon.backgroundColor = [UIColor redColor];

}


- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {

    checked_icon = [cell.contentView viewWithTag:1234];

    if (cell.isSelected == YES) {
        [cell setBackgroundColor:[UIColor lightGrayColor]];
        checked_icon.backgroundColor = [UIColor redColor];

    }

    else {
        [cell setBackgroundColor:[UIColor whiteColor]];
        checked_icon.backgroundColor = [UIColor clearColor];
    }
}

@end
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top