我接管了一个iOS项目,并且必须将视图列表重构为UITableView。我正在使用Storyboard并且已经将UITableViewCell子类化了。一个子类称为MenuItemCell,它有一个headerLabel,detailLabel和priceLabel,它们是在Storyboard中设置并在MenuItemCell中配置的属性。我可以像这样通过cellForAtIndexPath来操作这些:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *MenuItemCellIdentifier=@"MenuItemCell";
id dic=self.tmpMenu.listItems[indexPath.row];
if([dic isKindOfClass:[MenuItem class]]){
MenuItemCell *cell = [self.menuTV dequeueReusableCellWithIdentifier:MenuItemCellIdentifier];
MenuItem *menuItem=(MenuItem *)dic;
cell.menuItem=menuItem;
cell.headerLabel.text=menuItem.header;
cell.headerLabel.numberOfLines=0;
cell.priceLabel.text=menuItem.price;
// how to handle this custom spotView
if([menuItem hasInstoreImage]){
UIView *instoreImageDot=[self circleWithColor:[UIColor redColor] radius:4];
[cell.spotView addSubview:instoreImageDot]; // ON SCROLLING, this populates to all the different table cells
}
return cell;
}
return nil;
}
最后一部分是有一个名为spotView的自定义UIView。目前,我通过circleWithColor在我的控制器中的代码中创建这个圆圈并尝试添加到[cell.spotView]但滚动导致它填充在不同的表格单元格上。我怎么设置这个?我已经在我的自定义视图中添加了一个方法,但这也遇到了同样的问题。
thx任何帮助
答案 0 :(得分:2)
单元格被重用,您需要告诉tableView删除自定义视图
if([menuItem hasInstoreImage]){
UIView *instoreImageDot=[self circleWithColor:[UIColor redColor] radius:4];
[cell.spotView addSubview:instoreImageDot];
}else{
//remove it if condition is not met
//or You can add a place holder view instead
}
答案 1 :(得分:1)
正在发生的事情是iOS在滚动时重复使用单元格,并且一些重用的单元格已经将instoreImageDot视图添加为子视图。
你真的不应该在cellForRowAtIndexPath方法中做布局。它应该只用于使可重复使用的单元出列,然后设置单元的数据。所有布局内容都应该由单元本身处理。
不要在控制器中创建instoreImageDot。在自定义单元格中添加一个方法 - 类似于(用C#编写,但应该很容易翻译):
UpdateCell(MenuItem item, bool hasInstoreIamge)
{
menuItem = item;
headerLabel.text = item.header;
priceLabel.text = item.price;
headerLabel.numberOfLines=0;
if (hasInstoreImage)
{
// code to add the instoreImageDot as a subview of the cell
}
}
同样在Custom Cell中,实现prepareForReuse方法并在此方法中,从单元格中删除instoreImageDot视图 - 这样它只能添加一次。
- (void)prepareForReuse {
if([self.subviews containsObject:instoreImageDot])
{
[instoreImageDot removeFromSuperview];
}
[super prepareForReuse];
}
现在你的cellForRowAtIndexPath方法看起来像:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *MenuItemCellIdentifier=@"MenuItemCell";
id dic=self.tmpMenu.listItems[indexPath.row];
if([dic isKindOfClass:[MenuItem class]]){
MenuItemCell *cell = [self.menuTV dequeueReusableCellWithIdentifier:MenuItemCellIdentifier];
MenuItem *menuItem=(MenuItem *)dic;
cell.UpdateCell(menuItem, [menuItem hasInstoreImage]);
return cell;
}
return nil;
}