我有一个tableview,它接收一个由字典组成的数组。每个字典都有一个AVAsset和音频数据。我在每个自定义tableview单元格中都有一个UIView,它显示AVAsset
的波形,并在选择特定单元格时播放音频数据。每次使用addObject向数组添加字典时,tableview都能正常工作。但是,我希望最新的字典位于tableView的顶部,所以我使用insertObject:AtIndex:0
,但由于某种原因,添加到数组的第一个字典的UIView
保持在顶部单元格,其他UIViews根本不加载。但是,每个音频数据都在正确的单元格中。因此,如果我在数组中有三个字典,则只有第一个字典的UIView
显示在顶部单元格中,其下方有两个空单元格。奇怪的部分是每个字典的音频数据与正确的单元格相关联。超级混乱,但我很确定这与tableview单元格的UIView
如何在重新加载tableview时响应有关。随机地,我可以得到第二个UIView,但它不一致。对不起,如果这让你头疼!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString* word = @"audioTableCell";
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"audioTableCell" owner:self options:nil];
OSAudioTableCell *cell =[self.audioTable dequeueReusableCellWithIdentifier:word];
if(!cell)
{
cell= (OSAudioTableCell*)[nib objectAtIndex:0];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
//Dictionary from the array
NSDictionary * packageInArray = [self.audioTableArray objectAtIndex:indexPath.row];
//Not related to UIView
cell.userName.text = [packageInArray objectForKey:@"userName"];
cell.profilePicture.image = [UIImage imageWithData:[packageInArray objectForKey:@"profileImageData"]];
//This is for the UIView
[cell setProgress:0];
[cell setAsset:[packageInArray objectForKey:@"asset"]];
[cell setBackgroundColor:[UIColor clearColor]];
[cell.waveView setBackgroundColor:[UIColor clearColor]];
//Not related to UIView
CALayer *imageLayer = cell.profilePicture.layer;
[imageLayer setCornerRadius:20];
imageLayer.borderColor = (__bridge CGColorRef)([UIColor grayColor]);
[imageLayer setMasksToBounds:YES];
}
return cell;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[arrayStatusLabel setHidden:YES];
self.primaryUser = [OSPrimaryUser getUserInstance];
self.primaryUser.userAudioArray = [self.primaryUser createAudioArray];
self.audioTableArray = self.primaryUser.userAudioArray;
[self.audioTable registerNib:[UINib nibWithNibName:@"audioTableCell" bundle:nil] forCellReuseIdentifier:@"audioTableCell"];
if([self.audioTableArray count] == 0)
{
[self.audioTable setHidden:YES];
[arrayStatusLabel setHidden:NO];
}
else
{
[self.audioTable setHidden:NO];
[arrayStatusLabel setHidden:YES];
}
[self.navigationItem setHidesBackButton:YES];
[self.audioTable setSeparatorInset:UIEdgeInsetsZero];
[self.audioTable reloadData];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self.audioTable reloadData];
if([self.audioTableArray count] == 0)
{
[self.audioTable setHidden:YES];
[arrayStatusLabel setHidden:NO];
}
else
{
[self.audioTable setHidden:NO];
[arrayStatusLabel setHidden:YES];
}
}
-(void) viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self.audioTable reloadData];
}
答案 0 :(得分:0)
我认为问题在于您将所有数据添加到if(!cell)子句中的单元格中。最佳做法是在viewDidLoad中注册您的nib(使用registerNib:forIdentifier :)而不是手动加载nib。您将保证以这种方式获取单元格,并且您可以一起消除if(!cell)子句。关于CALayer的最后一段代码并不需要在每次调用cellForRowAtIndexPath:方法时运行,因此我将该代码移动到单元的init方法。
编辑后:
-(void)viwDidLoad {
[super viewDidLoad];
[self.tableView registerNib:[UINib nibWithNibName:@"OSAudioTableCell" bundle:nil] forCellReuseIdentifier:@"audioTableCell"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString* word = @"audioTableCell";
OSAudioTableCell *cell =[self.audioTable dequeueReusableCellWithIdentifier:word];
// configure your cell
return cell;
}
只要您在cellForRowAtIndexPath中使用相同的标识符" audioTableCell",就可以保证获得有效的单元格。
答案 1 :(得分:0)
在我看来,当你做从dequeueReusableCellWithIdentifier接收一个对象时,你只是重新使用那个单元格而不更新其中的值。
也就是说,你有:
OSAudioTableCell *cell =[self.audioTable dequeueReusableCellWithIdentifier:word];
if (!cell)
{
// create a cell ...snip
// set all the cell content ...snip
}
// You probably want to set the cell content...
// ...out here, instead.
return cell;
在你的问题中写的方式(我假设你从你的项目中复制/粘贴),每个重复使用的单元格将只显示它之前的任何信息。
在编辑中添加:了解一下,当您创建一个包含100行的表时,iOS确实= = =分配100个单元格,每行一个。相反,它只为屏幕上的内容分配足够的单元格 - 可能是7或8,具体取决于表格和行的高度 - 然后,当一个单元格滚出屏幕时,它会被放入队列中下次调用dequeueReusableCellWithIdentifier时重用:
因此,第二次获取单元格时,视图已包含您上一次初始化的所有子视图。
rdelmar
的答案显示了如何正确创建基于nib的单元格。重要的是:在之后填充单元格的内容您有一个有效的单元格,而不是仅在您创建它时,这是您的代码片段显示的内容。请记住:第17行的单元格可能是用于第3行的回收单元格。
所有单元格内容视图 - 显示波形,进度条,图像或单元格中的任何其他内容的视图 - 需要在<<>之后设置的值和/或内容 / strong>您确认自己有一个有效的单元格, 后验证您是否拥有有效的观看次数。
对于非基于nib的单元格,它通常看起来像这样(在浏览器中键入;可能需要调整):
OSAudioTableCell *cell =[self.audioTable dequeueReusableCellWithIdentifier:word];
if (cell == nil)
{
// create a cell
[[UITableViewCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: CellIdentifier];
}
UILabel *cellLabel = [cell viewWithTag: kMyLabelTag];
if (myLabel == nil)
{
cellLabel = [UILabel new];
cellLabel = kMyLabelTag;
// set-up frame, whatever else...
[cell addSubView: cellLabel];
}
cellLabel = someGoodText; // NOTE: we do this whether the field is new or old!
SpecialView *cellView = [cell viewWithTag: kMyViewTag];
if (cellView == nil)
{
cellView = [SpecialView new];
cellView = kMyViewTag;
// set-up frame, whatever else...
[cell addSubView: cellView];
}
cellView.specialField = someValue; // NOTE: we do this whether the field is new or old!
// etc., repeat for other cell-content.
return cell;
对于基于nib的单元格,从笔尖加载各种子视图,因此您可以假设它们存在并跳过if (cellSubView == nil) createCelLSubview
部分。
希望有所帮助!