如何使用UITableViews深入查看plist?

时间:2013-08-19 19:19:25

标签: ios objective-c xcode uitableview plist

我想使用uitableviews钻取一个plist来获得特定的学校。下钻到州 - >区 - >学校。我创造了一个plist,但我不能100%确定结构是最好的。此外,我可以在第一个tableview上获得第一组活动信息,但我不知道如何从那里开始。我是否需要为每次下钻(stateview,districtview,schoolview)创建一个tableview,或者我可以重用通用的tableview,因为它们很简单就是列表吗?以下是我到目前为止的情况。谢谢你的帮助。

PLIST
<plist version="1.0">
<array>
<dict>
    <key>districts</key>
    <dict>
        <key>District 1</key>
        <array>
            <string>School 2</string>
            <string>School 1</string>
        </array>
        <key>District 2</key>
        <array>
            <string>School 3</string>
            <string>School 4</string>
        </array>
    </dict>
    <key>state</key>
    <string>South Dakota</string>
</dict>
<dict>
    <key>districts</key>
    <array>
        <string>District 1</string>
        <string>District 2</string>
    </array>
    <key>state</key>
    <string>Arkansas</string>
</dict>
<dict>
    <key>districts</key>
    <array>
        <string>District 3</string>
        <string>District 4</string>
    </array>
    <key>state</key>
    <string>New York</string>
</dict>
</array>
</plist>

这是我的viewcontroller

#import "plistViewController.h"

@interface plistViewController ()

@end

@implementation plistViewController

- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {

}
return self;
}

@synthesize content = _content;

-(NSArray *)content
{
if (!_content) {
    _content = [[NSArray alloc] initWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"Data" ofType:@"plist"]];
}
return _content;
}

- (void)viewDidLoad
{
[super viewDidLoad];

}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];

}

#pragma mark - Table view data source

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

return [self.content count];
}

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

cell.textLabel.text = [[self.content objectAtIndex:indexPath.row] valueForKey:@"state"];
return cell;
 }


#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
}

@end

3 个答案:

答案 0 :(得分:2)

关于UITableView的最好的事情是它不关心它显示的数据。它只询问delegate几个不同的问题:

  1. 我应该有多少个部分?
  2. 每个部分中有多少行?
  3. 我可以为此 _ 索引路径设置UITableViewCell吗?
  4. 因此,您必须专注于使您的委托响应提供正确的数据。

    所以,首先将你的plist分成可管理的块。 UITableView prima-donna dataSource是一个NSArray。由于索引逻辑,它整齐地映射到tableViews。

    也就是说,你的第一个tableViewController plistViewController具有良好的显示信息的逻辑。具体来说,您在数组位置x查询NSDictionary并要求它返回其state对象。 3个字典对象,返回3个字符串。好的。

    那么你如何进入下一个级别?您的tableView将在这里为您提供帮助。它询问了delegate

    的具体问题
    1. 当用户触摸Section Y Row X时,我该怎么办?
    2. 您将需要设置另一个名为DistrictViewController的UITableViewController子类。在标头.h文件中,您需要为strong对象创建NSDictionary属性。像这样:

      //DistrictViewController.h
      @interface DistrictViewController : UITableViewController
      @property (nonatomic, strong) NSDictionary *districtDictionary;
      @end
      
      //DistrictViewController.m
      @implementation DistrictViewController
      @synthesize districtDictionary;
      

      我们有它。此类现在设置为跟踪1个NSDictionary对象。现在,您只需配置表委托方法即可显示所需的数据。

      第一个例子,在NSArray的顶行(索引:0)中,你有一个包含2个键的字典:District 1District 2。但这是一个问题。 NSDictionary没有很容易映射到TableViews,因为NSDictionary对象不使用索引来工作。不要担心。 NSDictionary有一个名为allKeys的方法,它将为您提供字典中每个键的数组。当你从某个地方收到一个NSDictionary但不知道它预先包含哪些键时,这很有用。

      所以,你的tableView问的问题,让我们回答:

      //How many sections will be in me: Let's just say 1 for now.
      //How many rows will be in this section:
      
      //Ask the NSDictionary how many keys it has:
      NSArray *keyArray = [self.districtDictionary allKeys];
      return [keyArray count];
      
      //Give me a tableCell for index path X,Y
      
      
      //First, get your array of keys back:
      NSArray *keyArray = [self.districtDictionary allKeys];
      //Next, find the key for the given table index:
      NSString *myKey = [keyArray objectAtIndex:indexPath.row];
      //Finally, display this string in your cell:
      cell.textLabel.text = myKey;
      

      在此之后,你会为最终视图做同样的事情。为学校设置一个viewController并将其命名为SchoolViewController,并将其设置为负责NSArray。就像以前一样:

      @interface SchoolViewController : UITableViewController
      @property (nonatomic, strong) NSArray *schoolArray;
      @end
      
      @implementation SchoolViewController
      @synthesize schoolArray;
      

      在这个视图中,它将与第一个很相似。你只需要这个viewController就像之前那样回答表的问题:

      1. 多少个部分?我们需要1
      2. 多少行?我们需要尽可能多的数组return [schoolArray count];
      3. 给我一个单元格:cell.textLabel.text = [schoolArray objectAtIndex:indexPath.row];
      4. 将这一切放在一起的最后一篇文章是表格中的最后一个问题。

        1. 当用户触摸一行时我该怎么办?
        2. 在每个视图中,查看此方法签名:

          -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
          

          这是您添加逻辑以解决问题的地方。在第一个视图plistViewController中,执行以下操作:

          NSDictionary *topLevelDictionary = [self.content objectAtIndex:indexPath.row];
          NSDictionary *allDistricts = [topLevelDictionary objectForKey:@"districts"];
          DistrictViewController *dView = [[DistrictViewController alloc] initWithStyle:UITableViewStylePlain];
          dView.districtDictionary = allDistricts;
          [self.navigationController pushViewController:dView animated:YES];
          

          在第二个视图中,DistrictViewController执行此操作:

          NSArray *keyArray = [self.districtDictionary allKeys];
          NSString *myKey = [keyArray objectAtIndex:indexPath.row];
          NSArray *schoolArray = [self.districtDictionary objectForKey:myKey];
          SchoolViewController *sView = [[SchoolViewController alloc]initWithStyle:UITableViewStylePlain];
          sView.schoolArray = schoolArray;
          [self.navigationController pushViewController:sView animated:YES];
          

          我希望这会对你有所帮助。我在纯文本编辑器中输入了这一切。希望没有拼写错误。你需要#import每个关联的viewControllers!祝你好运。

答案 1 :(得分:1)

创建下钻表:

Boys and Girls example

你可以这样做:

- (void)viewDidLoad
{
[super viewDidLoad];


NSArray *districts = [NSArray arrayWithObjects:@"district1", @"district2", @"district3", nil];
NSArray *states = [NSArray arrayWithObjects:@"NY", @"NJ", @"NO", @"StateOther1", @"StateOther2", nil];
NSArray *schools = [NSArray arrayWithObjects:@"", @"school1", @"school2", @"school3", @"school4", nil];

NSMutableDictionary *schoolSection = [NSMutableDictionary dictionary];
[schoolSection schools forKey:@"items"];
[schoolSection setObject:@"Shools" forKey:@"title"];

NSMutableDictionary *districtSection = [NSMutableDictionary dictionary];
[districtSection setObject:districts forKey:@"items"];
[districtSection setObject:@"Section" forKey:@"title"];

NSMutableDictionary *stateSection = [NSMutableDictionary dictionary];
[districtSection setObject:states forKey:@"items"];
[districtSection setObject:@"State" forKey:@"title"];

self.adresses = @[schoolSection, districtSection,stateSection];
}

下一步:

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

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSDictionary *currentSection = [self.adresses objectAtIndex:section];
if ([[currentSection objectForKey:@"isOpen"] boolValue]) {
    NSArray *items = [currentSection objectForKey:@"items"];
    return items.count;
}
return 0;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                  reuseIdentifier:CellIdentifier];
}

NSDictionary *currentSection = [self.adresses objectAtIndex:indexPath.section];
NSArray *items = [currentSection objectForKey:@"items"];
NSString *currentItem = [items objectAtIndex:indexPath.row];
cell.textLabel.text = currentItem;

return cell;
}

下一步:

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
NSDictionary *currentSection = [self.adresses objectAtIndex:section];
NSString *sectionTitle = [currentSection objectForKey:@"title"];
BOOL isOpen = [[currentSection objectForKey:@"isOpen"] boolValue];
NSString *arrowNmae = isOpen? @"arrowUp":@"arrowDown";

UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
button.frame = CGRectMake(0.0f, 0.0f, 320.0f, 50.0f);
button.tag = section;
button.backgroundColor = [UIColor brownColor];
[button setTitle:sectionTitle forState:UIControlStateNormal];
[button addTarget:self action:@selector(didSelectSection:)
 forControlEvents:UIControlEventTouchUpInside];
[button setImage:[UIImage imageNamed:arrowNmae] forState:UIControlStateNormal];
return button;
}

下一步:

- (void)didSelectSection:(UIButton*)sender {
//get current section
NSMutableDictionary *currentSection = [self.adresses objectAtIndex:sender.tag];

//get elements of section
NSArray *items = [currentSection objectForKey:@"items"];

//create array of indexes
NSMutableArray *indexPaths = [NSMutableArray array];
for (int i=0; i<items.count; i++) {
    [indexPaths addObject:[NSIndexPath indexPathForRow:i inSection:sender.tag]];
}

//get current state  of section is opened
BOOL isOpen = [[currentSection objectForKey:@"isOpen"] boolValue];

//set new state
[currentSection setObject:[NSNumber numberWithBool:!isOpen] forKey:@"isOpen"];

//animate of adding and deleting of cells
if (isOpen) {
    [self.tableView deleteRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationTop];
} else {
    [self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationTop];
}

//reload button image
NSString *arrowNmae = isOpen? @"arrowDown.png":@"arrowUp.png";
[sender setImage:[UIImage imageNamed:arrowNmae] forState:UIControlStateNormal];
}

您可以根据需要自定义此表。 您可以下载的深入研究表示例here(单击“Скачать”按钮)

答案 2 :(得分:0)

您应该将区域数组传递给可以显示它们的新视图控制器。新的视图控制器应该有一个名为districts的属性,我还建议创建一个初始化器,它接受一组设置此属性的区域。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSArray *districts = [[self.content objectAtIndex:indexPath.row] valueForKey:@"districts"];
    DistrictsViewController *districtsvc =  
     [[DistrictsViewController alloc] initWithNibName:nil 
                                               bundle:nil 
                                            districts:districts];
    [self.navigationController pushViewController:districtsvc];
}

从你的例子中我不知道学校信息会从哪里来,所以如果很难说你是否能够轻松地创建一个通用的视图控制器来从一个州钻到学校。