0

我在 UITableView 中有一个导航菜单。

我的单元格中装有以下内容:

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

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

        UIView *topSplitterBar = [[UIView alloc] initWithFrame:CGRectMake(0, 0, cell.bounds.size.width, 1)];
        topSplitterBar.backgroundColor = [UIColor colorWithRed:62.0/255.0 green:69.0/255.0 blue:85.0/255.0 alpha:1];
        [cell.contentView addSubview:topSplitterBar];
    }

    // Set a boolean to determine if the item in the menu is the currently displayed VC on the main stack
    BOOL currentDisplayed = NO;


    cell.textLabel.backgroundColor = [UIColor clearColor];
    cell.textLabel.textColor = [UIColor colorWithRed:196.0/255.0 green:204.0/255.0 blue:218.0/255.0 alpha:1];
    cell.textLabel.font = [UIFont systemFontOfSize:18.0f];
    cell.textLabel.shadowColor = [UIColor colorWithRed:27.0/255.0 green:31.0/255.0 blue:41.0/255.0 alpha:1];
    cell.textLabel.shadowOffset = CGSizeMake(0, 1);

    UIView *selectedBg = [[UIView alloc] init];
    selectedBg.backgroundColor = [UIColor colorWithRed:50.0/255.0 green:56.0/255.0 blue:73.0/255.0 alpha:1];
    selectedBg.clipsToBounds = YES;
    UIView *topSplitterBar2 = [[UIView alloc] initWithFrame:CGRectMake(0, 0, cell.bounds.size.width, 1)];
    topSplitterBar2.backgroundColor = [UIColor yellowColor];
    [selectedBg addSubview:topSplitterBar2];
    [cell setSelectedBackgroundView:selectedBg];

    // Configure the cell...
    if (indexPath.section == 0 ) {
        if ([self.slidingViewController.topViewController isKindOfClass:[MESProfileViewController class]]) {
            currentDisplayed = YES;
        }
        cell.textLabel.text = NSLocalizedString(@"LMDisplayName", @"Left Menu - displayname");
    } else {
        switch ( indexPath.row ) {
            case 0: {
                if ([self.slidingViewController.topViewController isKindOfClass:[MESHomeViewController class]]) {
                    currentDisplayed = YES;
                } 
                cell.textLabel.text = NSLocalizedString(@"LMGames", @"Left Menu - Games");
                break ;
            }
            case 1: {
                cell.textLabel.text = NSLocalizedString(@"LMShare", @"Left Menu - Share");
                break ;
            }
            case 2: {
                cell.textLabel.text = NSLocalizedString(@"LMRate", @"Left Menu - Rate");
                break ;
            }
            case 3: {
                if ([self.slidingViewController.topViewController isKindOfClass:[MESSettingsViewController class]]) {
                    currentDisplayed = YES;
                }
                cell.textLabel.text = NSLocalizedString(@"LMSettings", @"Left Menu - Settings");
                break ;
            }
            case 4: {
                cell.textLabel.text = NSLocalizedString(@"LMHelp", @"Left Menu - Help");
                break ;
            }
            case 5: {
                cell.textLabel.text = NSLocalizedString(@"LMLogout", @"Left Menu - Log out");
                break ;
            }
        }
    }

    if (currentDisplayed) {
        // This is for the current item that is being displayed
        cell.contentView.backgroundColor = [UIColor colorWithRed:50.0/255.0 green:56.0/255.0 blue:73.0/255.0 alpha:1];
        UIImage *arrowImage = [UIImage imageNamed:@"selectedArrow"];
        UIImageView *arrow = [[UIImageView alloc] initWithFrame:CGRectMake(240, 10, arrowImage.size.width, arrowImage.size.height)];
        arrow.image = arrowImage;
        [cell.contentView addSubview:arrow];
    } else {
        cell.contentView.backgroundColor = [UIColor colorWithRed:75.0/255.0 green:83.0/255.0 blue:102.0/255.0 alpha:1.0];
        NSLog(@"%@",cell.textLabel.text);
        NSLog(@"%@",cell.contentView.subviews);
    }

    return cell;
}

然后在 didSelectCell 中重新加载一组单元格(可以显示为当前单元格)以更改背景。

NSIndexPath* displayNameRow = [NSIndexPath indexPathForRow:0 inSection:0];
NSIndexPath* gamesRow = [NSIndexPath indexPathForRow:0 inSection:1];
NSIndexPath* settingsRow = [NSIndexPath indexPathForRow:3 inSection:1];
NSArray* rowsToReload = [NSArray arrayWithObjects:displayNameRow, gamesRow, settingsRow, nil];
[weakSelf.tableView reloadRowsAtIndexPaths:rowsToReload withRowAnimation:UITableViewRowAnimationNone];

我发现每次重新加载单元格时都会再次创建 UIView *topSplitterBar 并将其添加到 cell.contentView 中?

我认为重新加载单元格会清除所有子视图并从头开始创建。我应该如何更改此实现以不继续添加这些视图。如果它是当前单元格,我还有另一个用于添加箭头的 UIImageView,其效果与上面相同,因此最终我的单元格中不需要很多额外的视图。

背景:这是一个侧视图控制器(滑入)菜单表视图。选定的单元格显示当前选择已显示为主顶视图控制器。

4

1 回答 1

0

您应该更改 的实现cellForRowAtIndexPath,以便它不会一次又一次地添加子视图。我已经写了一个带有评论的实施草案。

//Here you might get a reusable cell with dequeuing so your subviews are already there, just do customization on the subviews
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    //If you haven't got a reusable cell create a new one with all default subview properties
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];

    UIView *topSplitterBar = [[UIView alloc] initWithFrame:CGRectMake(0, 0, cell.bounds.size.width, 1)];
    topSplitterBar.backgroundColor = [UIColor colorWithRed:62.0/255.0 green:69.0/255.0 blue:85.0/255.0 alpha:1];
    [cell.contentView addSubview:topSplitterBar];
}

//Do all your customization afterwards, identifying cells based on indexPath
...

这是关于https://stackoverflow.com/a/3490460/837244问题的简洁答案(不是公认的答案),公认的答案说解决方案 B 会起作用,但实际上它会重复添加子视图,如评论中所述。

于 2013-05-09T12:03:01.517 回答