【问题标题】:How to reloadCells correctly如何正确重新加载Cells
【发布时间】:2013-05-09 11:56:10
【问题描述】:

我在 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,其效果与上面相同,因此最终我的单元格中不需要很多额外的视图。

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

【问题讨论】:

    标签: ios ios5 uitableview


    【解决方案1】:

    您应该更改cellForRowAtIndexPath 的实现,这样它就不会一次又一次地添加子视图。我已经用 cmets 编写了一个实现草案。

    //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 会起作用,但实际上它会重复添加子视图,如 cmets 中所述。

    【讨论】:

    • 谢谢,但这似乎实际上完全阻止了该视图的添加。
    • 为什么?您将其添加到 if 块内的语句 [cell.contentView addSubview:topSplitterBar];
    • 我已经用该方法的完整代码更新了这个问题,以帮助解释这里正在做什么
    • 第一次加载时,单元格为零,因此未加载该视图。
    • 故事板中是否有具有相同标识符的原型单元格,这可能是它不返回 nil 的原因。看看这个问题以获得更多解释stackoverflow.com/a/10255020/837244
    猜你喜欢
    • 2014-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-23
    • 1970-01-01
    • 2015-12-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多