iOS - 包含数组数据的简单表格部分

时间:2013-11-20 22:54:40

标签: ios uitableview

我刚刚开始使用iOS / Xcode并且已经使用Googling / Youtubing一个小时而无法找到匹配的教程。我现在要做的就是显示一个表格,其中列出了按bodypart(部分)分组的练习(行)列表。 bodypart部分永远不会改变,但用户可以将自定义练习添加到bodypart。

现在,我假设我需要一个数组用于各个部分,还有一个数组用于练习......创建它们很简单。我遇到了将练习分配到特定部分的问题。这是一个错误代码的示例,渲染时,在两个部分下都显示两个练习...也没有在表格中生成任何部分名称,所以我不确定它在哪里发挥作用。

以下是结果的屏幕截图(作为旁注,不确定我的导航控制器无法渲染的原因):http://i.imgur.com/icoJgEq.jpg

创建单个项目:

@property NSString *exerciseName;
@property NSString *exerciseCategoryName;

创建/分配数组:

@property NSMutableArray *exerciseCategories;
@property NSMutableArray *exercises;

self.exerciseCategories = [[NSMutableArray alloc]init];
self.exercises = [[NSMutableArray alloc]init]; 

使用一些默认数据填充数组:

- (void)loadInitialData {
    FNTExerciseCategories *category1 = [[FNTExerciseCategories alloc]init];
    category1.exerciseCategoryName = @"Chest";
    [self.exerciseCategories addObject:category1];
    FNTExerciseCategories *category2 = [[FNTExerciseCategories alloc]init];
    category2.exerciseCategoryName = @"Biceps";
    [self.exerciseCategories addObject:category2];

    FNTExercises *exercise1 = [[FNTExercises alloc]init];
    exercise1.exerciseName = @"Bench Press";
    [self.exercises addObject:exercise1];
    FNTExercises *exercise2 = [[FNTExercises alloc]init];
    exercise2.exerciseName = @"Barbell Curl";
    [self.exercises addObject:exercise2];
}

加载数据:

[self loadInitialData];

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return [self.exerciseCategories count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return [self.exercises count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"ExercisePrototypeCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    // Configure the cell...
    MFTExercises *exercise = [self.exercises objectAtIndex:indexPath.row];
    cell.textLabel.text = exercise.exerciseName;
    return cell;
}

非常感谢任何可以加入的人!

2 个答案:

答案 0 :(得分:3)

实际上在tableView:numberOfRowsInSection:中,您将返回整个exercises数组的计数。因此,对于您的示例数据,每个部分将有两行。尝试为每个部分制作一系列练习,然后编写如下代码:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    if (section == 0) {
        return [self.chestExercises count];
    }
    else if (section == 1) {
        return [self.bicepsExercises count];
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"ExercisePrototypeCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    // Configure the cell...
    MFTExercises *exercise;
    if (indexPath.section == 0) {
        exercise = [self.chestExercises objectAtIndex:indexPath.row];
    }
    else if (indexPath.section == 1) {
        exercise = [self.bicepsExercises objectAtIndex:indexPath.row];
    }
    cell.textLabel.text = exercise.exerciseName;
    return cell;
}

在这种情况下,chestExercises数组只包含“Bench Press” - 练习,而bicepsExercises只包含“Barbell Curl” - 练习。所以每个部分你会得到一行。

为了实现这些部分具有标题,您需要实现该方法

- (NSString *)tableView:(UITableView *)aTableView titleForHeaderInSection:(NSInteger)section {
    return [self.exerciseCategories objectAtIndex:section];
}

根据存储在数组中的名称为节提供标题。

构建数据源的一种更复杂的方法是创建一个NSDictionary,其中节名称为键(bodyparts),值为包含bodypart练习的数组。例如,如果您的类别只是字符串,您可以使用您的示例数据构建这样的字典(为了演示的目的,我添加了另一个练习):

FNTExerciseCategories *category1 = [[FNTExerciseCategories alloc]init];
category1.exerciseCategoryName = @"Chest";
[self.exerciseCategories addObject:category1];
FNTExerciseCategories *category2 = [[FNTExerciseCategories alloc]init];
category2.exerciseCategoryName = @"Biceps";
[self.exerciseCategories addObject:category2];

FNTExercises *exercise1 = [[FNTExercises alloc]init];
exercise1.exerciseName = @"Bench Press";
FNTExercises *exercise2 = [[FNTExercises alloc]init];
exercise2.exerciseName = @"Barbell Curl";
FNTExercises *exercise3 = [[FNTExercises alloc]init];
exercise3.exerciseName = @"Another Exercise";

// the instance variable self.exercises is a NSMutableDictionary now of course
self.exercises = [[NSMutableDictionary alloc] init];
exercises[category1.exerciseCategoryName] = @[exercise1];
exercises[category2.exerciseCategoryName] = @[exercise2, exercise3];

这里的优点是你现在有一个字典,其中包含包含所有数据的所有数组。因此,当您添加更多数据时,您无需更改tableView数据源的实现。 BTW我正在使用Modern Objective-C语法来编写字典和数组。

创建了这样的字典后,您就可以像这样简单地实现表视图数据源:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.

    // This gives the name of the category at the current section. 
    // It is then used as a key for the dictionary.
    NSString *currentCategory = [[self.exerciseCategories objectAtIndex:section] exerciseCategoryName];
    return [self.exercises[currentCategory] count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"ExercisePrototypeCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    // Configure the cell...
    NSString *currentCategory = [[self.exerciseCategories objectAtIndex:indexPath.section] exerciseCategoryName];

    MFTExercises *exercise = [self.exercises[currentCategory] objectAtIndex:indexPath.row];

    cell.textLabel.text = exercise.exerciseName;
    return cell;
}

使用NSDictionary可能会或可能不会使您的应用受益,但您不必为每个身体部位创建一个数组作为实例变量。将单个字典保存到磁盘以保持持久性也可能更容易。

答案 1 :(得分:2)

首先,您应该使用WWDC UITableView部分练习它。有许多源代码使用UITableView,UICollectionView和UIScrollView。

你需要在代码中返回你需要为exerciseCategories返回section标题,你只定义了section - (NSInteger)numberOfSectionsInTableView :( UITableView *)tableView这个委托函数,但你要返回该节的所有nil值此刻的标题。

- (NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    FNTExerciseCategories *category = [self.exerciseCategories objectAtIndex:section];
    return category. exerciseCategoryName;
}

这将显示您的部分。但是你需要考虑数据的结构,因为现在你没有为你刚刚返回的每个部分返回正确的数字[self.exercises count]。

要渲染UINavigationController,您需要推送视图而不是将视图作为模态。

[self.navigationController pushViewController:exerciseView animated:YES];