English 中文(简体)
IOS:阻止在UITableView中错误重复使用单元格
原标题:IOS: Stop cells being incorrectly reused in UITableView

我有一个基本的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];`
最佳回答

每种类型的内容都需要不同的重用标识符。因此,这里有两种类型的内容——具有UIButton的单元格和没有UIButtonUIButton的单元格。

使用 indexPath tableView:CellforRowAtIndexPath: 方法来选择“Cellwood button”或“Celloutout button”的再利用标识符。

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

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

问题回答

在DashboardCell中,创建一个属性@属性(非原子,赋值)BOOL按钮Enabled。然后在唤醒Nib时,始终创建按钮并设置button.hidden=YES

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

最后重写prepareForReuse

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

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

根据章节的不同,您可以使用两个不同的单元格标识符。否则,您需要查看从返回的单元格中是否存在该按钮,并在必要时添加或删除一个现有按钮。

如果你打算重用这些单元格,并且显示或隐藏每个单元格的按钮背后有一些简单的逻辑,我建议你首先在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;
}

在你的cell子类中,你会有方法-(void)setupWithSomeOptions:(SomeOptions)SomeOptions,大致如下:

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

    self.myButtonOutlet.hidden = someOptions.somePropertyToCheckIfButtonShouldBeHidden;

    // some more setup code
}




相关问题
List Contents of Directory in a UITableView

I am trying to list the contents of Ringtones directory in a TableView, however, I am only getting the last file in the directory in ALL cells, instead of file per cell. This is my code: - (...

iPhone NSUserDefaults persistance difficulty

In my app i have a bunch of data i store in the NSUserdefaults. This information consists of an NSObject (Object1) with NSStrings and NSNumbers and also 2 instances of yet another object (Object2). ...

Writing a masked image to disk as a PNG file

Basically I m downloading images off of a webserver and then caching them to the disk, but before I do so I want to mask them. I m using the masking code everyone seems to point at which can be found ...

Resize UIImage with aspect ratio?

I m using this code to resize an image on the iPhone: CGRect screenRect = CGRectMake(0, 0, 320.0, 480.0); UIGraphicsBeginImageContext(screenRect.size); [value drawInRect:screenRect blendMode:...

Allowing interaction with a UIView under another UIView

Is there a simple way of allowing interaction with a button in a UIView that lies under another UIView - where there are no actual objects from the top UIView on top of the button? For instance, ...