使用嵌套在 NSDictionary plist 中的数组中的第二个元素 [1] 的字符串填充 tableview
Posted
技术标签:
【中文标题】使用嵌套在 NSDictionary plist 中的数组中的第二个元素 [1] 的字符串填充 tableview【英文标题】:Populating a tableview with strings which are the second element [1] in arrays which are nested into NSDictionary plist 【发布时间】:2013-09-24 00:22:45 【问题描述】:我正在使用情节提要为 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。非常简单的 plist 我已经很好地工作了,似乎是这个嵌套的业务让我绊倒了。
* 10 月 29 日更新 ...我现在已删除 plist *
所以。如何使用嵌套字典 plist 正确访问信息并填充表格。同样,这是使用嵌套字典。这是我不知道该怎么做的,这是我正在努力学习的。
【问题讨论】:
我为 Wild and Smash 做了@synthesize 你能用plist内容更新问题吗? 与您的问题无关,但是为什么您在使用dequeueReusableCellWithIdentifier
重用单元格后分配另一个单元格?
currentManeuverName
为零吗?
感觉您的问题是在寻求代码解决方案,而您最好深入研究 plist 并在需要时提出更具体的问题。有多种方法可以满足您的要求(例如使用表格部分或将数组复制到表格数组属性等)
【参考方案1】:
用问题中的 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;
【讨论】:
xcode 似乎不喜欢 KEY_SECOND_ELEMENT ...它也不喜欢 "cell.textLabel = [data objectAtIndex:indexPath.row];"所以我把它改成了“[[cell textLabel] setText:[data objectAtIndex:indexPath.row]];”它喜欢哪个。 使用未声明的标识符“KEY_SECOND_ELEMENT” 当然,KEY_SECOND_ELEMENT 是您在 PLIST 上的关键,我编辑我的答案 @interface EonOrderOfPrinciple : UIViewController首先,您需要将 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
【讨论】:
这告诉我(使用一些 NSLogging)没有字符串被传递到 currentManeuverName ......即使只是 NSLogging [Smash objectAtIndex:1] 返回(null)。看来我们仍然没有从 plist 中获取该字符串。 我构建了一个新的 plist,以 Wild 作为 Root(字典)并且只有 Smash 数组,并且此代码适用于此。如果 Wild 是要嵌套到另一个字典中的字典让我们说 plist root Maneuvers(字典)......我将如何访问它? 我已经用它所拥有的所有信息更新了 plist,目前大部分都不需要。【参考方案3】:我相信您希望将您的 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;
【讨论】:
是的,您可能需要解释一下父键是什么,如果他知道如何使用桥接表和外键,我相信他不会问这个问题!无论如何都是好的解决方案!【参考方案4】:我认为你加载数据很好,如果你在某个地方这样做
Smash = (NSArray*)[Wild objectForKey:@"WhateverKeyIsForWild"];
在访问之前。
我不认为您的问题是嵌套字典或 PList 或任何东西,因为您已经让它在这里和那里工作。 (我会通过 cmets,而不是任何其他留言板)。
我相信吸引您的是 ios。您的加载功能是否在您访问数组之前发生?尝试通过在 Smash 访问数据时记录其内容来测试它是否加载了数据。
NSLog(@"%@", Smash); // should automatically dump its contents into the logger
如果没有任何内容、nil、垃圾、意外数据,那么您必须遵循您的代码并确保首先发生加载,否则内存不会被垃圾回收。
尝试禁用 ARC,您可以将代码复制并粘贴到没有它的新项目中。因为什么都不会改变(因为如果你只是测试几个字符串,泄漏是可以的)。如果它有效,你知道 ARC 就是它。
表的生命周期很有趣,也有点烦人,因为在操作顺序方面您只有几件事可以依靠。
嗯,这个答案比我想要的要长得多,对此我深表歉意。怪 ARC。
【讨论】:
另外,这个问题请大家在这里交流一下,除了light cmets ;) 记录以后会对你有帮助的。以上是关于使用嵌套在 NSDictionary plist 中的数组中的第二个元素 [1] 的字符串填充 tableview的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Swift 将新数组数据添加到 plist 文件中的 NSDictionary