IOS:停止在UITableView中错误地重用单元格

Jer*_*emy 2 cells switch-statement uibutton uitableview ios

我有一个基本的UITableView有四个部分.我用Switch语句控制每个部分的内容.

我以编程方式创建一个按钮,该按钮应出现在前三个部分的行中,但不应出现在第四个部分中.但是,按钮在第四部分的行中随机出现.

我认为这是因为一个单元正在被重用,但是当我使用Switch语句创建每个部分的行时,我看不出这是怎么回事.任何想法都赞赏.

我正在使用配置的自定义单元格:`

static NSString *CustomCellIdentifier = @"DashboardCell";

DashboardCell *cell = (DashboardCell *)[tableView dequeueReusableCellWithIdentifier: CustomCellIdentifier];

if (cell == nil) { NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"DashboardCell"
                                                                owner:self options:nil];
    for (id oneObject in nib) if ([oneObject isKindOfClass:[DashboardCell class]])
        cell = (DashboardCell *)oneObject;
}

// Configure the cell.`
Run Code Online (Sandbox Code Playgroud)

创建此按钮的代码是:`

        button = [UIButton buttonWithType:UIButtonTypeCustom];
        button.frame = CGRectMake(200, 11, 50, 50);        
        UIImage *iConnect = [UIImage imageNamed:@"connect.png"];
        [button setImage:iConnect forState:UIControlStateNormal];
        [button addTarget:self action:@selector(buttonSelected:) forControlEvents:UIControlEventTouchUpInside];
        [cell addSubview:button];`
Run Code Online (Sandbox Code Playgroud)

Bar*_*vel 11

每种类型的内容都需要不同的重用标识符.所以这里有两种类型的内容 - 具有a的UIButton单元格和不具有的单元格.

使用indexPath所述的tableView:cellForRowAtIndexPath:方法以选择@"CellWithButton"或@"CellWithoutButton"的重用标识符.

代码中实际发生的是所有单元都被赋予相同的重用标识符,这意味着它们都被放入同一个对象池中.这意味着当您使用它时[tableView dequeueReusableCellWithIdentifier: CustomCellIdentifier];,您正在从这个池中检索一个单元格(可能包含没有UIButton单元格和单元格的单元格).因此,出列方法可以随机返回已经UIButton添加了它的单元格.如果您使用两个重用标识符,UITableView将设置两个对象池,并将正确地存储和检索每个对象池中的相应单元格.

或者,您可以使用一个重用池,并在UIButton每次使用dequeue方法检索单元格时检查单元格.


小智 7

在DashboardCell中,创建一个属性@property (nonatomic, assign) BOOL buttonEnabled.然后在你的awakeFromNib,总是创建按钮并设置button.hidden = YES.覆盖您的属性的setter

- (void)setButtonEnabled:(BOOL)enabled {
   buttonEnabled = enabled;
   button.hidden = !enabled;
}
Run Code Online (Sandbox Code Playgroud)

最后覆盖 prepareForReuse

- (void)prepareForReuse {
   [super prepareForReuse];
   self.buttonEnabled = NO;
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以在方法cellForRowAtIndexPath的配置部分中进行enbale/disable