2

我有一个基本的 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.`

创建此按钮的代码是:`

        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];`
4

4 回答 4

11

您需要为每种类型的内容使用不同的重用标识符。所以在这里你有两种类型的内容——有 a 的UIButton单元格和没有的单元格。

使用方法indexPathtableView:cellForRowAtIndexPath:选择@"CellWithButton" 或@"CellWithoutButton" 的重用标识符。

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

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

于 2012-05-27T17:12:49.570 回答
7

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

- (void)setButtonEnabled:(BOOL)enabled {
   buttonEnabled = enabled;
   button.hidden = !enabled;
}

最后覆盖prepareForReuse

- (void)prepareForReuse {
   [super prepareForReuse];
   self.buttonEnabled = NO;
}

现在您可以在方法 cellForRowAtIndexPath 的配置部分中启用/禁用

于 2012-05-27T16:10:19.443 回答
1

您可以根据部分使用两种不同的单元格标识符。否则,您需要查看返回的单元格中是否存在按钮,dequeueReusableCellWithIdentifier:并在必要时添加或删除现有按钮。

于 2012-05-27T15:59:18.523 回答
0

如果您要重用这些单元格,并且在显示或隐藏每个单元格的按钮背后有一些简单的逻辑,我建议您在 Interface Builder 中创建按钮并将其作为插座连接到您的 UITableViewDelegate。

然后,我将为单元创建一个设置方法,您可以在任何时间运行任意次数而不会破坏它:

-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
    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.
    [cell setupWithSomeConfigOptions:someConfigOptions]

    return cell;
}

在您的单元子类中,您将拥有 method -(void)setupWithSomeOptions:(SomeOptions)someOptions,它类似于:

-(void)setupWithSomeOptions:(SomeOptions)someOptions
{
    // some setup code

    self.myButtonOutlet.hidden = someOptions.somePropertyToCheckIfButtonShouldBeHidden;

    // some more setup code
}
于 2012-05-27T17:43:46.323 回答