基本上我正在创建一个列表视图,您可以将内容添加到顶部。我能想到的最好的方法是将UITableViewCells本身存储在NSMutableArray中 - 因为我可以简单地将它们从数组中拉出来,并将所有数据都放在对象中,这个列表视图永远不会超过10个单元格。 / p>
另请注意,我正在使用Storyboard,因此initWithCoder使用。
以下代码是我正在尝试的,但它不起作用:
// This is where my NSMutableArray is initialized:
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder]) {
if (!_CellsArray) {
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"TestCell"];
_CellsArray = [NSMutableArray arrayWithObject:cell];
}
}
return self;
}
//UITableView Delegate & DataSource Methods
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"TestCell"];
[_CellsArray insertObject:cell atIndex:0];
return [_CellsArray objectAtIndex:indexPath.row];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 10;
}
我意识到我可能会以错误的方式接近这个,这就是为什么我在这里虽然:)
谢谢。
编辑:在代码中修复了一个类型(TimerCell - > UITableViewCell)
答案 0 :(得分:3)
让我们看一下调用的顺序和发生的事情。
您的视图控制器已取消归档,因此会调用您的initWithCoder:
方法。此方法创建一个可变数组,并将TimerCell
的一个实例放入其中。所述实例未进一步配置(除非您已覆盖initWithStyle:reuseIdentifier:
以进行某些配置)。
调用您的数据源方法tableView:numberOfRowsInSection:
,它告诉表视图有十行。
因此,您的tableView:cellForRowAtIndexPath:
被称为十次。每次,它都会创建一个UITableViewCell
的新实例,并将其插入到可变数组中。 (在十次调用之后,你的可变数组在索引10处包含一个TimerCell
,在索引0-9处包含十个UITableViewCell
。)它没有配置单元格的内容或外观,然后返回单元格指定的行索引。在第一次调用时,系统会要求您输入第0行,因此将返回您刚创建并在索引0处插入的单元格。在第二次调用时,系统会要求您输入第1行,因此会返回数组中索引1处的单元格 - 因为您刚刚在索引0处插入了新单元格,因此您在上次调用时创建的单元格已转移到索引1 ,你又回来了。每次调用都会继续:您返回相同的未配置UITableViewCell
十次。
看起来你正试图超越UIKit。这几乎从来都不是一件好事。 (据说过早优化是万恶之源。)
UITableView
已经有了一种细胞重用机制;最好只跟踪你自己的单元内容并让这个机制做它的事情。我花了这么长时间才输入这个,其他的答案已经写成描述如何做到这一点。查看它们,或Apple的文档或任何第三方UITableView
教程。
答案 1 :(得分:0)
为什么不将单元格信息存储在数组中。然后在-cellForRowAtIndexPath:
方法中,只提取更改每个单元格所需的数据。
这是一个简单的例子:
//Lets say you have an init like this that inits some cell information
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder]) {
cellArray = [NSArray alloc] initWithObjects:@"firstCell",@"secondCell",@"thirdCell",nil];
}
return self;
}
//then for each cell, just extract the information using the indexPath and change the cell that way
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
cell.textLabel.text = [cellArray objectAtIndex:indexPath.row];
return cell;
}
答案 2 :(得分:0)
表视图不存储内容。相反,他们只是要求他们想要显示的数据,并且您通常从其他地方获取数据(如NSArray或NSFetchedResultsController)。只需将您想要的东西存储到某个数据容器中,然后让表格为您显示它们。
// Probably your data model is actually a member of your class, but for purposes of demonstration...
static NSArray* _myArray = [[NSArray alloc] initWithObjects:@"Bob", @"Sally", @"Joe", nil];
- (NSInteger) tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section
{
return [_myArray count];
}
- (UITableViewCell*) tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
static NSString* CellIdentifier = @"TestCell";
// Make a cell.
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if( cell == nil ) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Setup the cell with the right content.
NSString* aString = [_myArray objectAtIndex:[indexPath row]];
cell.textLabel = aString;
return cell;
}
现在,如果您想在列表中添加更多内容,请将其添加到您的阵列中,然后就完成了。
编辑:另一方面,initWithCoder:通常不是为视图控制器进行初始化的最佳位置。理由是,在它被调用的时候,很有可能还没有加载东西(例如IBOutlets)。我倾向于更喜欢viewDidLoad(在这种情况下不要忘记在viewDidUnload中清理)或awakeFromNib。