iOS:UITableViewController - cellForRowAtIndexPath单元格创建 [英] iOS: UITableViewController -- cellForRowAtIndexPath cell creation
问题描述
我知道苹果的文档没有指定cellForRowAtIndexPath顺序,即首先它会去到部分0,索引0;然后第0节,索引2;然后是第1节,索引0 ....等。我认为它跳。
下面是什么是更好的方法?目前我不断收到错误
NSRangeException',原因:'*** - [__ NSArrayM objectAtIndex:]:index 3超出范围[0 ... 2]'
错误出现b / c我认为cellForRowAtIndexPath跳转并标记
* sectioned = NULL
,因此跳过条件,并转到空数组或通过转到错误的条件超过索引计数。
以下是代码:
...声明并合成
NSManaged * object;
@property(strong,nonatomic)NSNumber * sevenDaysSectionFilled;
@property(strong,nonatomic)NSNumber * fourteenDaysSectionFilled;
@property(strong,nonatomic)NSNumber * thirtyDaysSectionFilled;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
object = NULL;
static NSString * CellIdentifier = @Cell;
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if(indexPath.section == 0)
{
if((SevenDaysArraySectioned == [NSNumber numberWithBool:YES])&&&&(sevenDaysSectionFilled!= [NSNumber numberWithBool :YES]))
{
object = [pastSevenDayArray objectAtIndex:indexPath.row];
sevenDaysSectionFilled = [NSNumber numberWithBool:YES];
}
else if((fourteenDaysArraySectioned == [NSNumber numberWithBool:YES])&& $ b object = [pastFourteenDaysArray objectAtIndex:indexPath.row];
fourteenDaysSectionFilled = [NSNumber numberWithBool:YES];
}
else if((thirtyDaysArraySectioned == [NSNumber numberWithBool:YES])&&(threeDaysSectionFilled!= [NSNumber numberWithBool:YES]))
{
object = [pastThirtyDaysArray objectAtIndex:indexPath.row];
thirtyDaysSectionFilled = [NSNumber numberWithBool:YES];
}
else if(indexPath.section == 1)
{
if((fourteenDaysArraySectioned == [NSNumber numberWithBool:YES])&& fourteenDaysSectionFilled!= [NSNumber numberWithBool:YES]))
{
object = [pastFourteenDaysArray objectAtIndex:indexPath.row];
fourteenDaysSectionFilled = [NSNumber numberWithBool:YES];
}
else if((thirtyDaysArraySectioned == [NSNumber numberWithBool:YES])&&(threeDaysSectionFilled!= [NSNumber numberWithBool:YES]))
{
object = [pastThirtyDaysArray objectAtIndex:indexPath.row];
thirtyDaysSectionFilled = [NSNumber numberWithBool:YES];
}
else if(indexPath.section == 2)
{
if((thirtyDaysArraySectioned == [NSNumber numberWithBool:YES])& 30DaysSectionFilled!= [NSNumber numberWithBool:YES]))
{
object = [pastThirtyDaysArray objectAtIndex:indexPath.row];
thirtyDaysSectionFilled = [NSNumber numberWithBool:YES];
}
}
NSString * entityName = [[object entity] name];
cell.textLabel.text = [NSString stringWithFormat:@%@%i,entityName,[indexPath row]];
object = NULL;
return cell;
}
请让我知道是否有更好的方法来完成。谢谢。
* 编辑
这有点复杂, / p>
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
numberOfSections = 0;
if([pastSevenDayArray count]> 0)numberOfSections ++;
if([pastFourteenDaysArray count]> 0)numberOfSections ++;
if([pastThirtyDaysArray count]> 0)numberOfSections ++;
if([pastSixtyDaysArray count]> 0)numberOfSections ++;
if([pastNinteyDaysArray count]> 0)numberOfSections ++;
if([pastArray count]> 0)numberOfSections ++;
[self numberOfCells];
return numberOfSections;
}
numberOfCells
- (void)numberOfCells
{
for(int section = 0; section< numberOfSections; section ++)
{
if == 0)
{
if([pastSevenDayArray count]> 0)
{
SevenDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionZeroCellCount = [pastSevenDayArray count];
sectionZeroHeader = sevenDaysSectionLabel;
}
else if([pastFourteenDaysArray count]> 0)
{
fourteenDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionZeroCellCount = [pastFourteenDaysArray count];
sectionZeroHeader = fourteenDaysSectionLabel;
}
else if([pastThirtyDaysArray count]> 0)
{
thirtyDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionZeroCellCount = [pastThirtyDaysArray count];
sectionZeroHeader = thirtyDaysSectionLabel;
}
else if([pastSixtyDaysArray count]> 0)
{
sixtyDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionZeroCellCount = [pastSixtyDaysArray count];
sectionZeroHeader = sixtyDaysSectionLabel;
}
else if([pastNinteyDaysArray count]> 0)
{
ninetyDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionZeroCellCount = [pastNinteyDaysArray count];
sectionZeroHeader = ninetyDaysSectionLabel;
}
else if([pastArray count]> 0)
{
pastArraySectioned = [NSNumber numberWithBool:YES];
sectionZeroCellCount = [pastArray count];
sectionZeroHeader = pastSectionLabel;
}
}
else if(section == 1)
{
if(([pastFourteenDaysArray count]> 0)&& (fourteenDaysArraySectioned!= [NSNumber numberWithBool:YES]))
{
fourteenDaysArraySectioned = [NSNumber numberWithBool:YES]
sectionOneCellCount = [pastFourteenDaysArray count];
sectionOneHeader = fourteenDaysSectionLabel;
}
else if(([pastThirtyDaysArray count]> 0)&&(thirtyDaysArraySectioned!= [NSNumber numberWithBool:YES]))
{
thirtyDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionOneCellCount = [pastThirtyDaysArray count];
sectionOneHeader = thirtyDaysSectionLabel;
}
else if(([pastSixtyDaysArray count]> 0)&&(sixtyDaysArraySectioned!= [NSNumber numberWithBool:YES]))
{
sixtyDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionOneCellCount = [pastSixtyDaysArray count];
sectionOneHeader = sixtyDaysSectionLabel;
}
else if(([pastNinteyDaysArray count]> 0)&&(ninetyDaysArraySectioned!= [NSNumber numberWithBool:YES]))
{
NinetyDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionOneCellCount = [pastNinteyDaysArray count];
sectionOneHeader = ninetyDaysSectionLabel;
}
else if(([pastArray count]> 0)&&(pastArraySectioned!= [NSNumber numberWithBool:YES]))
{
pastArraySectioned = [NSNumber numberWithBool:YES];
sectionOneCellCount = [pastArray count];
sectionOneHeader = pastSectionLabel;
}
}
else if(section == 2)
{
if(([pastThirtyDaysArray count]> 0)&&(thirtyDaysArraySectioned! [NSNumber numberWithBool:YES]))
{
thirtyDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionTwoCellCount = [pastThirtyDaysArray count];
sectionTwoHeader = thirtyDaysSectionLabel;
}
else if(([pastSixtyDaysArray count]> 0)&&(sixtyDaysArraySectioned!= [NSNumber numberWithBool:YES]))
{
sixtyDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionTwoCellCount = [pastSixtyDaysArray count];
sectionTwoHeader = sixtyDaysSectionLabel;
}
else if(([pastNinteyDaysArray count]> 0)&&(ninetyDaysArraySectioned!= [NSNumber numberWithBool:YES]))
{
NinetyDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionTwoCellCount = [pastNinteyDaysArray count];
sectionTwoHeader = ninetyDaysSectionLabel;
}
else if(([pastArray count]> 0)&&(pastArraySectioned!= [NSNumber numberWithBool:YES]))
{
pastArraySectioned = [NSNumber numberWithBool:YES];
sectionTwoCellCount = [pastarray count];
sectionTwoHeader = pastSectionLabel;
}
}
else if(section == 3)
{
NSLog(@Entered Section%i,section);
if(([pastSixtyDaysArray count]> 0)&&(sixtyDaysArraySectioned!= [NSNumber numberWithBool:YES])){
sixtyDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionThreeCellCount = [pastSixtyDrayArray count];
sectionThreeHeader = sixtyDaysSectionLabel;
}
else if(([pastNinteyDaysArray count]> 0)&&(ninetyDaysArraySectioned!= [NSNumber numberWithBool:YES]))
{
ninetyDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionThreeCellCount = [pastNinteyDaysArray count];
sectionThreeHeader = ninetyDaysSectionLabel;
}
else if(([pastArray count]> 0)&&(pastArraySectioned!= [NSNumber numberWithBool:YES]))
{
pastArraySectioned = [NSNumber numberWithBool:YES];
sectionThreeCellCount = [pastArray count];
sectionThreeHeader = pastSectionLabel;
}
}
else if(section == 4)
{
NSLog(@Entered Section%i,section);
if(([pastNinteyDaysArray count]> 0)&&(ninetyDaysArraySectioned!= [NSNumber numberWithBool:YES]))
{
ninetyDaysArraySectioned = [NSNumber numberWithBool:是];
sectionFourCellCount = [pastNinteyDaysArray count];
sectionFourHeader = ninetyDaysSectionLabel;
}
else if(([pastArray count]> 0)&&(pastArraySectioned!= [NSNumber numberWithBool:YES]))
{
pastArraySectioned = [NSNumber numberWithBool:YES];
sectionFourCellCount = [pastArray count];
sectionFourHeader = pastSectionLabel;
}
}
else if(section == 5)
{
NSLog(@Entered Section%i,section);
if(([pastArray count]> 0)&&(pastArraySectioned!= [NSNumber numberWithBool:YES]))
{
pastArraySectioned = [NSNumber numberWithBool:是];
sectionFiveCellCount = [pastArray count];
sectionFiveHeader = pastSectionLabel;
}
}
}
}
numberOfRowsInSection
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if(section == 0)
{
return sectionZeroCellCount;
}
else if(section == 1)
{
return sectionOneCellCount;
}
else if(section == 2)
{
return sectionTwoCellCount;
}
else if(section == 3)
{
return sectionThreeCellCount;
}
else if(section == 4)
{
return sectionFourCellCount;
}
if(section == 5)
{
return sectionFiveCellCount;
}
}
EDIT 2 p>
标题:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 30.0;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView * headerView = [[UIView alloc] initWithFrame :CGRectMake(0,0,tableView.bounds.size.width,150)];
UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(10,3,tableView.bounds.size.width - 10,25)];
label.backgroundColor = [UIColor clearColor];
[label setFont:[UIFont boldSystemFontOfSize:16]];
label.textColor = [UIColor whiteColor];
if(section == 0)
{
label.text = sectionZeroHeader;
}
else if(section == 1)
{
label.text = sectionOneHeader;
}
else if(section == 2)
{
label.text = sectionTwoHeader;
}
else if(section == 3)
{
label.text = sectionThreeHeader;
}
else if(section == 4)
{
label.text = sectionFourHeader;
}
else if(section == 5)
{
label.text = sectionFiveHeader;
}
[headerView addSubview:label];
return headerView;
}
被保持在不必是的各种实例变量中。我们可以使用集合和其他数据结构来建立表的定义,然后在数据源/委托方法中引用它。
这个视图控制器的基本思想是每个部分由一个 CVSectionModel
对象表示,该对象包含该部分的行数据和部分特定信息,例如头视图。在 viewDidLoad
中,我们构建这些节模型,并且每当我们完成更新数据时,我们应该重新构建它们。要尝试不同的数据工作安排,请使用其他测试方法之一替换 viewDidLoad
中的调用 testCase1
。
我们维护一个部分模型数组,并且只有在有内容时才为部分创建模型。正如你可以看到,这简化了什么数组的计算,以获取行信息,并在每个部分中有多少行。
请注意,此表控制器不支持更复杂的动画内容插入,删除或重新排序,因此如果这是一个要求,则需要额外的工作。它在更新后支持常规表重新加载,正如在viewDidLoad之后运行10秒的块中可以看到的。
请检查代码并询问任何问题。这是实现文件,但除了 @interface CVViewController:UIViewController @end
。
@interface CVSectionModel:NSObject
@property(nonatomic)NSArray * rowModels;
@property(nonatomic)NSString * sectionTitle;
@property(nonatomic)NSInteger标签; //可能对动画,区段上的不同行为有用等。
@end
@implementation CVSectionModel
@end
@interface CVViewController()< UITableViewDataSource,UITableViewDelegate>
@property(weak,nonatomic)IBOutlet UITableView * tableView;
@property(nonatomic)NSArray * sectionModels;
@property(非原子)NSArray * sevenDays;
@property(nonatomic)NSArray * fourteenDays;
@property(nonatomic)NSArray * thirtyDays;
@end
@implementation CVViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//在你的应用程序中,你将加载和处理你的真实数据
//但是这里我只是模拟一些字符串的例子
//调用其他方法尝试不同的配置
[self testCase1];
//我们在viewDidLoad上调用一次。你还要在每当更新底层数据时调用它,如下面的框中所示:
[self processSectionData];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@IDENTIFIER];
//证明支持修改底层数据并刷新视图。
//取消注释以测试它。
// double delayInSeconds = 10.0;
// dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW,(int64_t)(delayInSeconds * NSEC_PER_SEC));
// dispatch_after(popTime,dispatch_get_main_queue(),^(void){
// [self testCase2];
// [self processSectionData];
// [self。 tableView reloadData];
//});
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [self.sectionModels count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [((CVSectionModel *)self.sectionModels [ section])。
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:@ IDENTIFIER];
//在你的应用程序中,这似乎是一个类型的NSManagedObject,这里它只是一个字符串
NSString * modelForRow =((CVSectionModel *)self.sectionModels [indexPath.section])。rowModels [indexPath 。行];
cell.textLabel.text = modelForRow;
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 30.0;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
NSString * sectionTitle =((CVSectionModel *)self .sectionModels [section])。sectionTitle;
UIView * headerView = [[UIView alloc] initWithFrame:CGRectMake(0,0,tableView.bounds.size.width,150)];
UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(10,3,tableView.bounds.size.width - 10,25)];
label.backgroundColor = [UIColor clearColor];
[label setFont:[UIFont boldSystemFontOfSize:16]];
label.textColor = [UIColor whiteColor];
label.text = sectionTitle;
[headerView addSubview:label];
return headerView;
}
- (void)processSectionData
{
NSArray * allDayArrays = @ [self.sevenDays,self.fourteenDays,self.thirtyDays];
//你不会在这里使用硬编码的字符串 - 使用你的sevenDaysSectionLabel等变量
NSArray * labelTitles = @ [@7天,@14天,@30天];
NSMutableArray * mutableSectionModels = [NSMutableArray array];
[allDayArrays enumerateObjectsUsingBlock:^(NSArray * array,NSUInteger index,BOOL * stop){
if([array count]> 0){
CVSectionModel * sectionModel = [CVSectionModel alloc] init];
sectionModel.rowModels = array;
sectionModel.sectionTitle = labelTitles [index];
sectionModel.tag = index + 1; // track this to enable re-ordering in the future
[mutableSectionModels addObject:sectionModel];
}
}];
//如果Animating插入/删除将需要更复杂的
self.sectionModels = [mutableSectionModels copy];
}
//情况1:
//所有三个已填充
- (void)testCase1
{
self.sevenDays = @ [@sevendayitem1,@sevendayitem2,@sevendayitem3,@sevendayitem4];
self.fourteenDays = @ [@14day item 1,@14 day item 2];
self.thirtyDays = @ [@30天项目1,@30天项目2,@30天项目3];
}
//情况2:
// self.fourteenDays为空
- (void)testCase2
{
self.sevenDays = @ [@sevendayitem1,@sevendayitem2,@sevendayitem3,@sevendayitem4];
self.fourteenDays = @ [];
self.thirtyDays = @ [@30天项目1,@30天项目2,@30天项目3];
}
//情况3:
// self.thirtydays是唯一的一个
- (void)testCase3
{
self .sevenDays = @ [];
self.fourteenDays = @ [];
self.thirtyDays = @ [@30天项目1,@30天项目2,@30天项目3];
}
@end
I know the Apple docs do not specify that cellForRowAtIndexPath goes in order i.e. First it'll go to Section 0, Index 0; Then Section 0, Index 2; And then Section 1, Index 0....so on. I think it jumps around.
What's a better a way to a accomplish below? Currently I keep getting an error
NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 3 beyond bounds [0 .. 2]'
The error appears b/c I think cellForRowAtIndexPath jumps around and marks
*sectioned = NULL
, so the condition is skipped and it goes to an empty array or exceeds index count by going to a wrong condition.
Here is the code:
... declared and synthesized
NSManaged *object;
@property (strong, nonatomic) NSNumber *sevenDaysSectionFilled;
@property (strong, nonatomic) NSNumber *fourteenDaysSectionFilled;
@property (strong, nonatomic) NSNumber *thirtyDaysSectionFilled;
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
object = NULL;
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
if (indexPath.section == 0)
{
if ((SevenDaysArraySectioned == [NSNumber numberWithBool:YES]) && (sevenDaysSectionFilled != [NSNumber numberWithBool:YES]))
{
object = [pastSevenDayArray objectAtIndex:indexPath.row];
sevenDaysSectionFilled = [NSNumber numberWithBool:YES];
}
else if ((fourteenDaysArraySectioned == [NSNumber numberWithBool:YES]) && (fourteenDaysSectionFilled != [NSNumber numberWithBool:YES]))
{
object = [pastFourteenDaysArray objectAtIndex:indexPath.row];
fourteenDaysSectionFilled = [NSNumber numberWithBool:YES];
}
else if ((thirtyDaysArraySectioned == [NSNumber numberWithBool:YES]) && (thirtyDaysSectionFilled != [NSNumber numberWithBool:YES]))
{
object = [pastThirtyDaysArray objectAtIndex:indexPath.row];
thirtyDaysSectionFilled = [NSNumber numberWithBool:YES];
}
else if (indexPath.section == 1)
{
if ((fourteenDaysArraySectioned == [NSNumber numberWithBool:YES]) && (fourteenDaysSectionFilled != [NSNumber numberWithBool:YES]))
{
object = [pastFourteenDaysArray objectAtIndex:indexPath.row];
fourteenDaysSectionFilled = [NSNumber numberWithBool:YES];
}
else if ((thirtyDaysArraySectioned == [NSNumber numberWithBool:YES]) && (thirtyDaysSectionFilled != [NSNumber numberWithBool:YES]))
{
object = [pastThirtyDaysArray objectAtIndex:indexPath.row];
thirtyDaysSectionFilled = [NSNumber numberWithBool:YES];
}
else if (indexPath.section == 2)
{
if ((thirtyDaysArraySectioned == [NSNumber numberWithBool:YES]) && (thirtyDaysSectionFilled != [NSNumber numberWithBool:YES]))
{
object = [pastThirtyDaysArray objectAtIndex:indexPath.row];
thirtyDaysSectionFilled = [NSNumber numberWithBool:YES];
}
}
NSString *entityName = [[object entity]name];
cell.textLabel.text = [NSString stringWithFormat:@"%@ %i", entityName, [indexPath row]];
object = NULL;
return cell;
}
Please let me know if there is a better way to accomplish this. Thanks.
*Edit
This is a bit complicated but here it is:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
numberOfSections = 0;
if ([pastSevenDayArray count] > 0) numberOfSections++;
if ([pastFourteenDaysArray count] > 0) numberOfSections++;
if ([pastThirtyDaysArray count] > 0) numberOfSections++;
if ([pastSixtyDaysArray count] > 0) numberOfSections++;
if ([pastNinteyDaysArray count] > 0) numberOfSections++;
if ([pastArray count] > 0) numberOfSections++;
[self numberOfCells];
return numberOfSections;
}
numberOfCells
-(void)numberOfCells
{
for (int section = 0; section<numberOfSections; section ++)
{
if (section == 0)
{
if ([pastSevenDayArray count] > 0)
{
SevenDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionZeroCellCount = [pastSevenDayArray count];
sectionZeroHeader = sevenDaysSectionLabel;
}
else if ([pastFourteenDaysArray count] > 0)
{
fourteenDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionZeroCellCount = [pastFourteenDaysArray count];
sectionZeroHeader = fourteenDaysSectionLabel;
}
else if ([pastThirtyDaysArray count] > 0)
{
thirtyDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionZeroCellCount = [pastThirtyDaysArray count];
sectionZeroHeader = thirtyDaysSectionLabel;
}
else if ([pastSixtyDaysArray count] > 0)
{
sixtyDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionZeroCellCount = [pastSixtyDaysArray count];
sectionZeroHeader = sixtyDaysSectionLabel;
}
else if ([pastNinteyDaysArray count] > 0)
{
ninetyDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionZeroCellCount = [pastNinteyDaysArray count];
sectionZeroHeader = ninetyDaysSectionLabel;
}
else if ([pastArray count] > 0)
{
pastArraySectioned = [NSNumber numberWithBool:YES];
sectionZeroCellCount = [pastArray count];
sectionZeroHeader = pastSectionLabel;
}
}
else if (section == 1)
{
if (([pastFourteenDaysArray count] > 0) && (fourteenDaysArraySectioned != [NSNumber numberWithBool:YES]))
{
fourteenDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionOneCellCount = [pastFourteenDaysArray count];
sectionOneHeader = fourteenDaysSectionLabel;
}
else if (([pastThirtyDaysArray count] > 0) && (thirtyDaysArraySectioned != [NSNumber numberWithBool:YES]))
{
thirtyDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionOneCellCount = [pastThirtyDaysArray count];
sectionOneHeader = thirtyDaysSectionLabel;
}
else if (([pastSixtyDaysArray count] > 0) && (sixtyDaysArraySectioned != [NSNumber numberWithBool:YES]))
{
sixtyDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionOneCellCount = [pastSixtyDaysArray count];
sectionOneHeader = sixtyDaysSectionLabel;
}
else if (([pastNinteyDaysArray count] > 0) && (ninetyDaysArraySectioned != [NSNumber numberWithBool:YES]))
{
ninetyDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionOneCellCount = [pastNinteyDaysArray count];
sectionOneHeader = ninetyDaysSectionLabel;
}
else if (([pastArray count] > 0) && (pastArraySectioned != [NSNumber numberWithBool:YES]))
{
pastArraySectioned = [NSNumber numberWithBool:YES];
sectionOneCellCount = [pastArray count];
sectionOneHeader = pastSectionLabel;
}
}
else if (section ==2)
{
if (([pastThirtyDaysArray count] > 0) && (thirtyDaysArraySectioned != [NSNumber numberWithBool:YES]))
{
thirtyDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionTwoCellCount = [pastThirtyDaysArray count];
sectionTwoHeader = thirtyDaysSectionLabel;
}
else if (([pastSixtyDaysArray count] > 0) && (sixtyDaysArraySectioned != [NSNumber numberWithBool:YES]))
{
sixtyDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionTwoCellCount = [pastSixtyDaysArray count];
sectionTwoHeader = sixtyDaysSectionLabel;
}
else if (([pastNinteyDaysArray count] > 0) && (ninetyDaysArraySectioned != [NSNumber numberWithBool:YES]))
{
ninetyDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionTwoCellCount = [pastNinteyDaysArray count];
sectionTwoHeader = ninetyDaysSectionLabel;
}
else if (([pastArray count] > 0) && (pastArraySectioned != [NSNumber numberWithBool:YES]))
{
pastArraySectioned = [NSNumber numberWithBool:YES];
sectionTwoCellCount = [pastArray count];
sectionTwoHeader = pastSectionLabel;
}
}
else if (section ==3)
{
NSLog(@"Entered Section %i", section);
if (([pastSixtyDaysArray count] > 0) && (sixtyDaysArraySectioned != [NSNumber numberWithBool:YES])) {
sixtyDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionThreeCellCount = [pastSixtyDaysArray count];
sectionThreeHeader = sixtyDaysSectionLabel;
}
else if (([pastNinteyDaysArray count] > 0) && (ninetyDaysArraySectioned != [NSNumber numberWithBool:YES]))
{
ninetyDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionThreeCellCount = [pastNinteyDaysArray count];
sectionThreeHeader = ninetyDaysSectionLabel;
}
else if (([pastArray count] > 0) && (pastArraySectioned != [NSNumber numberWithBool:YES]))
{
pastArraySectioned = [NSNumber numberWithBool:YES];
sectionThreeCellCount = [pastArray count];
sectionThreeHeader = pastSectionLabel;
}
}
else if (section ==4)
{
NSLog(@"Entered Section %i", section);
if (([pastNinteyDaysArray count] > 0) && (ninetyDaysArraySectioned != [NSNumber numberWithBool:YES]))
{
ninetyDaysArraySectioned = [NSNumber numberWithBool:YES];
sectionFourCellCount = [pastNinteyDaysArray count];
sectionFourHeader = ninetyDaysSectionLabel;
}
else if (([pastArray count] > 0) && (pastArraySectioned != [NSNumber numberWithBool:YES]))
{
pastArraySectioned = [NSNumber numberWithBool:YES];
sectionFourCellCount = [pastArray count];
sectionFourHeader = pastSectionLabel;
}
}
else if (section ==5)
{
NSLog(@"Entered Section %i", section);
if (([pastArray count] > 0) && (pastArraySectioned != [NSNumber numberWithBool:YES]))
{
pastArraySectioned = [NSNumber numberWithBool:YES];
sectionFiveCellCount = [pastArray count];
sectionFiveHeader = pastSectionLabel;
}
}
}
}
numberOfRowsInSection
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == 0)
{
return sectionZeroCellCount;
}
else if (section == 1)
{
return sectionOneCellCount;
}
else if (section == 2)
{
return sectionTwoCellCount;
}
else if (section == 3)
{
return sectionThreeCellCount;
}
else if (section == 4)
{
return sectionFourCellCount;
}
if (section == 5)
{
return sectionFiveCellCount;
}
}
EDIT 2
Header:
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 30.0;
}
- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, 150)];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 3, tableView.bounds.size.width - 10, 25)];
label.backgroundColor = [UIColor clearColor];
[label setFont:[UIFont boldSystemFontOfSize:16]];
label.textColor = [UIColor whiteColor];
if (section == 0)
{
label.text = sectionZeroHeader;
}
else if (section == 1)
{
label.text = sectionOneHeader;
}
else if (section == 2)
{
label.text = sectionTwoHeader;
}
else if (section == 3)
{
label.text = sectionThreeHeader;
}
else if (section == 4)
{
label.text = sectionFourHeader;
}
else if (section == 5)
{
label.text = sectionFiveHeader;
}
[headerView addSubview:label];
return headerView;
}
There's a whole lot of state being maintained in various instance variables that doesn't have to be. We can use collections and other data structures to build a definition for how the table is supposed to be, and then refer to that in our data source / delegate methods.
The basic idea of this view controller is that each section is represented by a CVSectionModel
object that contains the row data for that section, and section-specific information such as header views. Inside viewDidLoad
we build these section models, and any time we finish updating our data we should re-build them. To try that different arrangements of data work, replace the call in viewDidLoad
to testCase1
with one of the other test methods.
We maintain an array of section models and only create a model for a section if there's content to show there. As you can see this simplifies the calculation of what array to get row information out of and how many rows go in each section. We simply ask the section model for a section what to do, rather than synchronize several different instance variables.
Note this table controller doesn't support more elaborate animations of content insertion, deletion, or reordering, so additional work would be needed if that's a requirement. It does support regular table re-loading after an update, though, as can be seen in the block that runs 10 seconds after viewDidLoad.
Please examine the code and ask any questions. This is the implementation file, but nothing was in the header except for @interface CVViewController: UIViewController @end
.
@interface CVSectionModel : NSObject
@property (nonatomic) NSArray *rowModels;
@property (nonatomic) NSString *sectionTitle;
@property (nonatomic) NSInteger tag; // possibly useful for animations, different behavior on section, etc.
@end
@implementation CVSectionModel
@end
@interface CVViewController () <UITableViewDataSource, UITableViewDelegate>
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@property (nonatomic) NSArray *sectionModels;
@property (nonatomic) NSArray *sevenDays;
@property (nonatomic) NSArray *fourteenDays;
@property (nonatomic) NSArray *thirtyDays;
@end
@implementation CVViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// In your application, you'll be loading and processing your real data
// But here I'm just going to simulate a number of cases with strings for illustration
// Call the other methods to try different configurations
[self testCase1];
// We call this once on viewDidLoad. You'll also want to call it whenever you update the underlying data, as in the block below
[self processSectionData];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"IDENTIFIER"];
// Demonstrate support for modifying the underlying data and refresh the view.
// Uncomment to test it.
// double delayInSeconds = 10.0;
// dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
// dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
// [self testCase2];
// [self processSectionData];
// [self.tableView reloadData];
// });
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [self.sectionModels count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [((CVSectionModel *)self.sectionModels[section]).rowModels count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"IDENTIFIER"];
// In your app this appears to be an NSManagedObject of some type, here it's just a string
NSString *modelForRow = ((CVSectionModel *)self.sectionModels[indexPath.section]).rowModels[indexPath.row];
cell.textLabel.text = modelForRow;
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 30.0;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
NSString *sectionTitle = ((CVSectionModel *)self.sectionModels[section]).sectionTitle;
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, 150)];
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 3, tableView.bounds.size.width - 10, 25)];
label.backgroundColor = [UIColor clearColor];
[label setFont:[UIFont boldSystemFontOfSize:16]];
label.textColor = [UIColor whiteColor];
label.text = sectionTitle;
[headerView addSubview:label];
return headerView;
}
- (void)processSectionData
{
NSArray *allDayArrays = @[self.sevenDays, self.fourteenDays, self.thirtyDays];
// You won't use hard-coded strings here - use your sevenDaysSectionLabel, etc. variables instead
NSArray *labelTitles = @[@"7 days", @"14 days", @"30 days"];
NSMutableArray *mutableSectionModels = [NSMutableArray array];
[allDayArrays enumerateObjectsUsingBlock:^(NSArray *array, NSUInteger index, BOOL *stop) {
if ([array count] > 0) {
CVSectionModel *sectionModel = [[CVSectionModel alloc] init];
sectionModel.rowModels = array;
sectionModel.sectionTitle = labelTitles[index];
sectionModel.tag = index+1; // track this to enable re-ordering in the future
[mutableSectionModels addObject:sectionModel];
}
}];
// If Animating insertions / deletions will require something more elaborate
self.sectionModels = [mutableSectionModels copy];
}
// Case 1:
// All three populated
- (void)testCase1
{
self.sevenDays = @[@"sevendayitem1", @"sevendayitem2", @"sevendayitem3", @"sevendayitem4"];
self.fourteenDays = @[@"14day item 1", @"14 day item 2"];
self.thirtyDays = @[@"30 day item 1", @"30 day item 2", @"30 day item 3"];
}
// Case 2:
// self.fourteenDays is empty
- (void)testCase2
{
self.sevenDays = @[@"sevendayitem1", @"sevendayitem2", @"sevendayitem3", @"sevendayitem4"];
self.fourteenDays = @[];
self.thirtyDays = @[@"30 day item 1", @"30 day item 2", @"30 day item 3"];
}
// Case 3:
// self.thirtydays is the only one
- (void)testCase3
{
self.sevenDays = @[];
self.fourteenDays = @[];
self.thirtyDays = @[@"30 day item 1", @"30 day item 2", @"30 day item 3"];
}
@end
这篇关于iOS:UITableViewController - cellForRowAtIndexPath单元格创建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!