NSMutableArray,pList,Tableview混乱和崩溃

时间:2011-04-13 00:59:55

标签: iphone cocoa-touch uitableview nsmutablearray plist

我有一个首选项视图,根据单击的分段控件显示不同的表视图。

我硬编码了一些NSMutableArrays来测试基本原理:

prefsIssuesList = [[NSMutableArray alloc] init];
[prefsIssuesList addObject:@"Governance"];
[prefsIssuesList addObject:@"Innovation and technology"];
...etc

prefsIndustriesList = [[NSMutableArray alloc] init];
[prefsIndustriesList addObject:@"Aerospace and defence"];
... etc

prefsServicesList = [[NSMutableArray alloc] init];
[prefsServicesList addObject:@"Audit and assurance"];
...etc

currentArray = [[NSMutableArray alloc] init];
currentArray = self.prefsIssuesList;

然后使用currentArray重新加载tableview,添加一个UITableViewCellAccessoryCheckmark。 一切正常。

但现在我想在pList文件中打开或关闭复选标记,然后再读回来。

理想情况下想要像这样的plist

Root    Dictionary
    Issues  Dictionary
        Governance         Number   1
        Innovation and technology  Number   0
        etc

我已经做到了这一点

// Designate plist file
NSString *path = [[NSBundle mainBundle] pathForResource: @"issues" ofType:@"plist"];
// Load the file into a Dictionary
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
self.allNames= dict;
[dict release];

NSLog(@"Dict is %@", allNames); // All the data in the pList file

NSMutableArray *issueSection = [allNames objectForKey:@"Issues"];
NSLog(@"Issues is %@", issueSection); // The data is the Issues Section

NSString *issueVal = [issueSection objectForKey:@"Governance"];
NSLog(@"Governance is %@", issueVal); //The value of the Governance key

但我真正想做的是循环问题字典并获得键/值对

key   =  cell.textLabel.text
value =  UITableViewCellAccessoryCheckmark / UITableViewCellAccessoryNone 
         depending wether it's 1 or 0

我假设我仍然可以像在硬编码版本中那样将三个NSMutableArrays中的一个分配给currentArray,并使用currentArray重新加载tableview。

然后修改此代码以构建tableview

NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];

NSString *key = [keys objectAtIndex:section];
NSArray *nameSection = [names objectForKey:key];

static NSString *CellIdentifier = @"Cell";

//UITableViewCell *cell = [self.prefsTableView dequeueReusableCellWithIdentifier:SectionsTableIdentifier];
UITableViewCell *cell = [self.prefsTableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil) {
    cell=[[[UITableViewCell alloc] 
           initWithFrame:CGRectZero
           reuseIdentifier: CellIdentifier] autorelease];
}

cell.textLabel.text = [nameSection objectAtIndex:row];
return cell;

但是我的大脑已经融化了,我今天花了大约六个小时阅读pLists,NSArrays,NSMutableDisctionaries,standardUserDefaults,但收效甚微。

我已经在UINavigationViews中设法使用UITableViews,使用SegmentedControls,下载异步XML,但现在我终于被卡住了,或者被炒了,或者两者兼而有之。什么应该是相当简单的键/值对。

有人想给我一些白痴指针吗?

1 个答案:

答案 0 :(得分:0)

打字出来导致另一篇文章,我需要一个小词让我回到正轨:)

使用pList中的键/值对来规定单元格的名称,以及用户是否选择了单元格。

plist基于这样的结构

Root    Dictionary
        Services    Dictionary
                    Peaches       String    1
                    Pumpkin       String    0

以下是我从pList中抓取三个Dictionary数组并使用键/值对重新加载tableview的方法,具体取决于触摸了哪个segmentControl:

- (void)viewDidLoad {
    [super viewDidLoad];

    // Designate plist file
    NSString *path = [[NSBundle mainBundle] pathForResource: @"issues" ofType:@"plist"];
    // Load the file into a Dictionary
    NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
    self.allNames= dict;
    [dict release];

    // Create the Named Dictionaries from Dictionary in pLIst
    NSMutableDictionary *allIssues = [self.allNames objectForKey:@"Issues"];
    self.prefsIssuesList = allIssues;
    [allIssues release];

    NSMutableDictionary *allIndustries = [self.allNames objectForKey:@"Industries"];
    self.prefsIndustriesList = allIndustries;
    [allIndustries release];

    NSMutableDictionary *allServices = [self.allNames objectForKey:@"Services"];
    self.prefsServicesList = allServices;
    [allServices release];

    // Assign the current Dictionary to out placeholder Dictionary 
    currentDict = [[NSMutableDictionary alloc] init];
    currentDict = self.prefsIssuesList;
}

然后设置表格单元格样式

- (UITableViewCell *)tableView:(UITableView *)prefsTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    NSUInteger row = [indexPath row];

    NSArray *keysArray = [self.currentDict allKeys];
    NSString *theKey = [keysArray objectAtIndex:row];
    NSString *theValue = [self.currentDict objectForKey: [keysArray objectAtIndex:row]];   

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [self.prefsTableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if(cell == nil) {
        cell=[[[UITableViewCell alloc] 
               initWithFrame:CGRectZero
               reuseIdentifier: CellIdentifier] autorelease];
    }

    cell.textLabel.text = theKey;

    if (theValue == @"0") { 
        cell.accessoryType = UITableViewCellAccessoryNone; 
    }else { 
        cell.accessoryType = UITableViewCellAccessoryCheckmark; 
    } 

    return cell;
}

最后的if子句似乎不起作用,我会将其作为一个新问题发布(除非有人快速评论!)

最后,segmentControls将不同的字典分配给占位符数组并重新加载tableview

这花了我很长的一天才弄清楚(作为一个noobie)所以我希望它可以帮助某人

-(IBAction) segmentedControlIndexChanged{
switch (self.segmentedControl.selectedSegmentIndex) {
    case 0:
        //currentArray = self.prefsIssuesList;
        currentDict = self.prefsIssuesList;
        break;
    case 1:
        //currentArray = self.prefsIndustriesList;
        currentDict = self.prefsIndustriesList;
        break;
    case 2:
        //currentArray = self.prefsServicesList;
        currentDict = self.prefsServicesList;
        break;

    default:
        //currentArray = self.prefsIssuesList;
        currentDict = self.prefsIssuesList;
        break;
}
[prefsTableView reloadData];

}

如果有更整洁或更好的方式,请大声喊叫