1

我正在使用情节提要为 iPad 开发一个项目。我正在尝试使用来自 plist 的数据填充我的 UITableView。Plist 有一个 NSDictionary,它又包含 9 个数组,每个数组包含三个元素(一个数字和两个字符串)。我想从每个数组(它是一个字符串)中获取第二个元素 [1] 并用这些字符串填充表。

来自头文件;

@interface EonOrderOfPrinciple : UIViewController
<UITableViewDataSource, UITableViewDelegate>
@property (strong, nonatomic) IBOutlet UITableView *formManeuvers;
@property (nonatomic, strong) NSDictionary *Wild;
@property (nonatomic, strong) NSArray *Smash;
@property (nonatomic, strong) NSArray *CloseCombat;
@property (nonatomic, strong) NSArray *HeadButt;
@property (nonatomic, strong) NSArray *Pummel;
@property (nonatomic, strong) NSArray *Obstacle;
@property (nonatomic, strong) NSArray *Confusion;
@property (nonatomic, strong) NSArray *ImpWeap;
@property (nonatomic, strong) NSArray *Rage;
@property (nonatomic, strong) NSArray *WildStorm;

从实施;

NSString *aFile = [[NSBundle mainBundle]
                        pathForResource:@"Wild" ofType:@"plist"];
Wild = [[NSDictionary alloc] initWithContentsOfFile:aFile];

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
        return 1;
}

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

    cell = [[UITableViewCell alloc]
                initWithStyle:UITableViewCellStyleDefault
                reuseIdentifier:@"cell"];

NSString *currentManeuverName;
currentManeuverName = [Smash objectAtIndex:1];
[[cell textLabel] setText:currentManeuverName];
return cell;
}
@end

我意识到我现在只给它一个细胞。我想一旦我得到一个工作,我就可以尝试让其余的人填充。现在我什至无法得到那个。

我没有找到任何教程,也没有帮助解释如何使用这样的嵌套数据。我尝试使用我发现的各种版本的东西,但没有任何效果。在转向 Core Data 之前,我想学习如何使用 plist。非常简单的 plists 我做得很好,似乎是这个嵌套的业务让我绊倒了。

* 10 月 29 日更新 ...我现在删除了 plist *

所以。如何使用嵌套字典 plist 正确访问信息并填充表格。同样,这是使用嵌套字典。这是我不知道该怎么做的,这是我正在努力学习的。

4

4 回答 4

0

我相信您想将您的 plist 加载到部分和行中,并将父键作为部分标题!以下是您可以通过 3 个简单步骤做到这一点的方法。

第 1 步:首先,您不需要很多属性来保存父键。只需添加两个类级别变量,如下所示:

@interface EonOrderOfPrinciple () {
    NSDictionary    *parentDict;
    NSArray         *parentKeys;
}

第 2 步:在方法中填充这些类级别的变量viewDidLoad

- (void)viewDidLoad {
    [super viewDidLoad];

    NSString *aFile = [[NSBundle mainBundle] pathForResource:@"Wild" ofType:@"plist"];

    parentDict = [NSDictionary dictionaryWithContentsOfFile:aFile];
    parentKeys = [parentDict allKeys];

    [self.formManeuvers reloadData];
}

第 3 步:然后将它们加载到您的表数据源方法中:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return parentKeys.count;
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    return parentKeys[section];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSString *parentKey     = parentKeys[section];
    NSDictionary *childDict = parentDict[parentKey];

    return [childDict allKeys].count;
}

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

    NSString *parentKey     = parentKeys[indexPath.section];
    NSDictionary *childDict = parentDict[parentKey];
    NSArray *childKeys      = [childDict allKeys];

    NSString *childKey   = childKeys[indexPath.row];
    cell.textLabel.text  = childDict[childKey][1];

    return cell;
}
于 2013-10-02T04:57:46.807 回答
0

首先,您需要将 plist 加载到字典中并从中提取数组:

NSString *plistFile = [[NSBundle mainBundle] pathForResource:@"Wild" ofType:@"plist"];
NSDictionary *Wild = [[NSDictionary alloc] initWithContentsOfFile:plistFile];

self.Smash = [Wild objectForKey:@"Smash"];
self.CloseCombat = [Wild objectForKey:@"CloseCombat"];
self.HeadButt = [Wild objectForKey:@"HeadButt"];
.
.
.

然后您需要将该数据与 UITableViewCell 相关联:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    if (cell == nil) {
        cell = [[UITableViewCell alloc]
                    initWithStyle:UITableViewCellStyleDefault
                    reuseIdentifier:@"cell"];
    }

    NSString *currentManeuverName;
    currentManeuverName = [Smash objectAtIndex:1];
    [[cell textLabel] setText:currentManeuverName];
    return cell;
}

@end
于 2013-09-27T08:06:29.837 回答
0

用问题中的 PLIST 回答:

我认为您需要对如何构建 PLIST 进行更多反思。

在你的情况下,我认为最好做这样的事情:

Wild.plist

// Choose your key

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
    <dict>
        <key>title</key>
        <string>Smash</string>
        <key>letter</key>
        <string>F</string>
        <key>id</key>
        <string>1</string>
    </dict>
    <dict>
        <key>title</key>
        <string>Close Combat</string>
        <key>letter</key>
        <string>W</string>
        <key>id</key>
        <string>2</string>
    </dict>
</array>
</plist>

在你的 .h

@interface MyViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

在你的 .m 中:

// Your keys depend of your PLIST
#define KEY_TITLE @"title"
#define KEY_LETTER @"letter"
#define KEY_ID @"id"

// Data from your plist
@property (nonatomic, weak) NSMutableArray *data

- (void)viewDidLoad 
{
    [super viewDidLoad];    

    NSArray *a = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Wild" ofType:@"plist"]];

    self.data = [NSMutableArray array];

    for (NSDictionary *dic in a)
        [data addObject:[dic objectForKey:KEY_TITLE]; // Define your key
}

#pragma mark - UITableViewDelegate
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _data.count;
}

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

    cell = [[UITableViewCell alloc]
                initWithStyle:UITableViewCellStyleDefault
                reuseIdentifier:@"cell"];

    cell.textLabel = [data objectAtIndex:indexPath.row];

    return cell;
}

PLIST之前的旧答案:

您需要在一个新的可变数组中获取 PLIST 文件的所有第二个元素,并将其声明为@property

@property (nonatomic, weak) NSMutableArray *data

在您的 viewDidLoad 中构建此数组:

(我认为您的 PLIST 带有一个数组作为第一个键,请添加您的 PLIST 以获取更多信息)。

- (void)viewDidLoad 
{
    [super viewDidLoad];    

    NSArray *a = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Wild" ofType:@"plist"]];

    self.data = [NSMutableArray array];

    for (NSDictionary *dic in a)
        [data addObject:[dic objectForKey:KEY_SECOND_ELEMENT]]; // KEY_SECOND_ELEMENT is the key on your plist
}

接下来为您的表格视图:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return _data.count;
}

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

    cell = [[UITableViewCell alloc]
                initWithStyle:UITableViewCellStyleDefault
                reuseIdentifier:@"cell"];

    cell.textLabel = [data objectAtIndex:indexPath.row];

    return cell;
}
于 2013-09-26T16:04:54.090 回答
0

我认为你加载数据就好了,如果你 Smash = (NSArray*)[Wild objectForKey:@"WhateverKeyIsForWild"]; 在访问之前做某处。

我不认为你的问题是嵌套字典或 PLists 或任何东西,因为你已经让它在这里和那里工作了。(我会看评论,而不是其他任何留言板)。

我相信得到你的是iOS。您的加载功能是否在您访问数组之前发生?尝试通过在访问数据时记录其内容来测试 Smash 是否加载了数据。

NSLog(@"%@", Smash); // should automatically dump its contents into the logger

如果没有任何内容、零、垃圾、意外数据,那么您必须遵循您的代码并确保首先发生加载,否则内存不会被垃圾收集。

尝试禁用 ARC,您可以将代码复制并粘贴到没有它的新项目中。因为什么都不会改变(因为如果你只是测试几个字符串,泄漏是可以的)。如果它有效,你知道 ARC 就是它。

表的生命周期很有趣,也有点烦人,因为在操作顺序方面您只有几件可以依靠的东西。

好吧,这个答案比我想要的要长得多,对此我深表歉意。责备ARC。

于 2013-11-04T05:42:27.373 回答