I want to display Plist to the UITableView .By my below code I can display one key values that is list of states. but i want to display all the values of three tables.
- (id)readPlist:(NSString *)fileName
{
NSData *plistData;
NSString *error;
NSPropertyListFormat format;
id plist;
NSString *localizedPath = [[NSBundle mainBundle] pathForResource:fileName ofType:#"plist"];
plistData = [NSData dataWithContentsOfFile:localizedPath];
plist = [NSPropertyListSerialization propertyListFromData:plistData mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&error];
if (!plist) {
NSLog(#"Error reading plist from file '%s', error = '%s'", [localizedPath UTF8String], [error UTF8String]);
}
return plist;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return [[[self readPlist:#"sample"] objectForKey:#"ListOfStates"] count];
}
- (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] autorelease];
}
cell.textLabel.text = [[[self readPlist:#"sample"] objectForKey:#"ListOfStates"] objectAtIndex:indexPath.row];
return cell;}
MY output comes only listofkeystates values
is it also possible to display key name with values
Maybe use table sections...
-(NSInteger) numberOfSectionsInTableView:(UITableView *)tableView {
NSDictionary* dict = [self readPlist:#"sample"];
return dict.allKeys.count;
}
-(NSString*) tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSDictionary* dict = [self readPlist:#"sample"];
return [dict.allKeys objectAtIndex:section];
}
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSDictionary* dict = [self readPlist:#"sample"];
NSString* key = [dict.allKeys objectAtIndex:section];
return [[dict valueForKey:key] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary* dict = [self readPlist:#"sample"];
NSString* key = [dict.allKeys objectAtIndex:indexPath.section];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = [[dict objectForKey:key] objectAtIndex:indexPath.row];
return cell;
}
just try to get data in NSDictionary and NSArray and then use it in UITableView
NSString *file = [[NSBundle mainBundle] pathForResource:#"sample" ofType:#"plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:file];
and use tableValue with its name like bellow...
NSArray *array = [dict objectForKey:#"ListOfStates"];
NSLog(#"%#", array);
i hope this help you..
EDIT : Corrected some typo mistakes
The idea
Loading plist in a dictonary
optional : sort it (!)
create the array of data for each section
create the array of section
Then implement the following things
viewDid load -> load the plist file in a dictionary, create an array of the sections and a dictionary of the data
numberOfSectionsInTableView -> the number of sections. In your case the number of keys
numberOfRowsInSection -> the number of rows of each section
titleForHeaderInSection -> for each section, the title of the section
cellForRowAtIndexPath -> the data of all row
sectionIndexTitlesForTableView -> the array that holds all you sections names. In your case all the keys
assuming you have a property called mySections and a property called myData
also assuming you use storyboard with standard cell with recycle identifier "Cell"
#synthesize mySections
#synthesize myData
- (void)viewDidLoad
{
[super viewDidLoad];
//LOADING THE PLIST FILE
//Create a string representing the file path
NSString *plistPath = [bundle pathForResource:#"yourFilename" ofType:#"plist"];
//Load the file in a dictionnary
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:plistPath];
self.myData = dict;
//SORTING THE DICTIONARY
NSArray *dicoArray = [[self.myData allKeys] sortedArrayUsingComparator:^(id firstObject, id secondObject) {
return [((NSString *)firstObject) compare:((NSString *)secondObject) options: NSCaseInsensitiveSearch];
}];
self.mySections = dicoArray;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
//Return the number of sections.
return [self.mySections count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
NSString *key = [self.mySections objectAtIndex:section];
NSArray *dataInSection = [self.myData objectForKey:key];
return [dataInSection count];
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSString *key = [self.mySections objectAtIndex:section];
return [NSString stringWithFormat:#"%#", key];
}
-(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return self.mySections;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
NSString *key = [self.mySections objectAtIndex:section];
NSArray *dataForSection = [self.myData objectForKey:key];
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"Cell" forIndexPath:indexPath];
cell.textLabel.text = [dataForSection objectAtIndex:row];
return cell;
}
Related
I have a plist with Dictionary and numbers of strings per dictionary.show into the url below.and this list of items is in thousands in the plist.
I need to display these plist data into the UItableview
.
How to do this?
My Code:
- (void)viewWillAppear:(BOOL)animated
{
// get paths from root direcory
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES);
NSString *documentsDirectory = [documentPaths objectAtIndex:0];
NSString *documentPlistPath = [documentsDirectory stringByAppendingPathComponent:#"p.plist"];
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:documentPlistPath];
valueArray = [dict objectForKey:#"title"];
self.mySections=[valueArray copy];
NSLog(#"value array %#",self.mySections);
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [self.mySections count];
}
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSString *key = [[self.mySections objectAtIndex:section]objectForKey:#"pass"];
return [NSString stringWithFormat:#"%#", key];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.mySections count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
}
// Configure the cell...
NSUInteger section = [indexPath section];
NSUInteger row = [indexPath row];
cell.textLabel.text = [[self.mySections objectAtIndex:row] objectForKey:#"title"];
cell.detailTextLabel.text=[[self.mySections objectAtIndex:section] objectForKey:[allKeys objectAtIndex:1]];
return cell;
}
You've run off the end of your array.
It's probably because you've hardcoded the number of rows for each section to be 5. Unless there really are 5 rows in each section, you should be returning a dynamic value here.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to Get Data from a PList into UITableView?
I have a plist with Dictionary and numbers of strings per dictionary.show into the url below.and this list of items is in thousands in the plist.
Now want to display these list into the tableview
.
now how can i display this plist into the UITableView
what I am trying is:
- (id)readPlist:(NSString *)fileName
{
NSString *error;
NSPropertyListFormat format;
id plist;
NSString *localizedPath = [[NSBundle mainBundle] pathForResource:#"A" ofType:#"plist"];
dic =[NSDictionary dictionaryWithContentsOfFile:localizedPath];
plist = [NSPropertyListSerialization propertyListFromData:dic mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&error];
if (!plist) {
NSLog(#"Error reading plist from file '%s', error = '%s'", [localizedPath UTF8String], [error UTF8String]);
[error release];
}
return plist;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
dict =[self readPlist:#"A"];
return dict.allKeys.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
dict = [self readPlist:#"A"];
key = [dict.allKeys objectAtIndex:section];
return [[dict valueForKey:key] count];
}
- (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] autorelease];
}
cell.textLabel.text = [[dict objectForKey:key] objectAtIndex:indexPath.row];
return cell;
}
UPDATE 2: You need to set the delegate and datasource for your tableView in your xib or ViewController.
In your ViewController.h file
#interface ViewController:UIViewController <UITableViewDelegate, UITableDataSource>
Try this code which I have written for you.
- (void)viewDidLoad {
tableView.delegate = self;
tableView.dataSource = self;
NSString *path = [[NSBundle mainBundle] pathForResource:#"Filename" ofType:#"plist"];
NSArray *contentArray = [NSArray arrayWithContentsOfFile:path];
// Having outlet for tableArray variable.
tableArray = [[NSMutableArray alloc]initWithArray:contentArray copyItems:YES];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [tableArray count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// In your case dictionary contains strings with keys and values. The below line returns dictionary only. not array..
NSDictionary *dictionary = [tableArray objectAtIndex:section];
return dictionary.allKeys.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = #"MyCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellIdentifier];
}
NSDictionary *dictionary = [tableArray objectAtIndex:indexPath.section];
NSArray *keysArray = dictionary.allKeys;
// This below line display the key in textLabel
cell.textLabel.text = [keysArray objectAtIndex:indexPath.row];
// Below line will display the value of a key in detailTextLabel.
cell.detailTextLabel.text = [dictionary valueForKey:[keysArray objectAtIndex:indexPath.row]];
return cell;
}
UPDATE 2: After I have seen your plist in my MAC, I have found out that we are working with array of dictionaries in your A.plist.
So I found there is a bug in our code itself. Not in the plist file and you can use your 8000 data plist too.. Its working too. I have checked out totally. Now you can get the above Code and start work with.
store Plist data in array
- (id)readPlist:(NSString *)fileName
{
NSString *error;
NSPropertyListFormat format;
id plist;
NSString *localizedPath = [[NSBundle mainBundle] pathForResource:#"A" ofType:#"plist"];
// declare your array in .h file
array = [NSArray arrayWithContentsOfFile:localizedPath];
plist = [NSPropertyListSerialization propertyListFromData:dic mutabilityOption:NSPropertyListImmutable format:&format errorDescription:&error];
if (!plist) {
NSLog(#"Error reading plist from file '%s', error = '%s'", [localizedPath UTF8String], [error UTF8String]);
[error release];
}
return plist;
}
and then write it in table
- (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] autorelease];
}
cell.textLabel.text = [array objectAtIndex:indexPath.row] valueForKey:#"keyname"];;
return cell;
}
I have data that is stored in a plist but when I pull it to my UITableView it gets reordered for some reason. Here are my table view data source methods:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [self.lunch_Dinner count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [[self.lunch_Dinner allKeys] objectAtIndex:section];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSString *typeOfEntree = [self tableView:tableView titleForHeaderInSection:section];
return [[self.lunch_Dinner valueForKey:typeOfEntree] count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"EntreeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
NSString *typeOfEntree = [self tableView:tableView titleForHeaderInSection:indexPath.section];
NSString *entree = [[self.lunch_Dinner valueForKey:typeOfEntree] objectAtIndex:indexPath.row];
cell.textLabel.text = entree;
return cell;
}
Here is the order of the plist:
Appetizers
Soups
Pastas
Pizzas
Specials
And this is the resulting order in the UITableView after being compiled:
Pizzas
Soups
Appetizers
Pastas
Specials
Any help would be great!
Thanks in advance.
If you want to store table in plist it is better to consider the following structure:
NSArray *sections = [NSArray arrayWithObjects:
[NSDictionary dictionaryWithObject:
[NSArray arrayWithObjects:row_1, row_2, ... , nil]
forKey:#"section name 1"],
[NSDictionary dictionaryWithObject:
[NSArray arrayWithObjects:row_1, row_2, ... , nil]
forKey:#"section name 2"],
...
[NSDictionary dictionaryWithObject:
[NSArray arrayWithObjects:row_1, row_2, ... , nil]
forKey:#"section name N"],
nil];
This code representation is easy to reproduce as plist. Create it as in example below
This structure can be easily used as UITableView datasource
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [self.datasource count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSDictionary *dict = [self.datasource objectAtIndex:section];
return [dict.allKeys lastObject];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSDictionary *dict = [self.datasource objectAtIndex:section];
return [dict.allValues.lastObject count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *dict = [self.datasource objectAtIndex:indexPath.section];
id cellPresenter = [dict.allValues.lastObject objectAtIndex:indexPath.row];
...
}
It looks like lunch_Dinner is a NSDictionary. NSDictionarys are unordered, so you are not guaranteed a specific output order from them.
It is a little hard to see exactly what value you're getting from having a key/value pair here, but one option would be to keep a separate NSArray with the correct ordering, and use that to correctly populate things.
I have the following code to make a table from string turned into a dictionary:
- (void)viewDidLoad {
[super viewDidLoad];
testArray = [[NSArray alloc] init];
NSString *testString = #"Sam|26,Hannah|22,Adam|30,Carlie|32";
testArray = [testString componentsSeparatedByString:#","];
dict = [NSMutableDictionary dictionary];
for (NSString *s in testArray) {
testArray2 = [s componentsSeparatedByString:#"|"];
[dict setObject:[testArray2 objectAtIndex:1] forKey:[testArray2 objectAtIndex:0]];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
if (testArray.count >indexPath.row) {
cell.textLabel.text = [[dict allKeys] objectAtIndex:[indexPath row]];
cell.detailTextLabel.text = [dict objectForKey:cell.textLabel.text];
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
What I would like is for the selected row title to be set as the title on my detail view.
I tried with:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.detailController.title = [[dict allKeys] objectAtIndex:[indexPath row]];
[self.navigationController pushViewController:self.detailController animated:YES];
}
But I get an "EXC_BAD_ACCESS" error.
It works fine if I use #"1" as title, it's just something with my dictionary call that's wrong, I assume.
Make dict a retained dictionary instead of an autoreleased one.
I.E. declare it maybe like this:
dict = [[NSMutableDictionary alloc] initWithCapacity: [testArray count]];
in your viewDidLoad method. Make sure to release it when viewDidUnload is called.
Also, make sure of the number of keys in your dict before calling:
self.detailController.title = [[dict allKeys] objectAtIndex:[indexPath row]];
So, I would do:
if(dict && ([[dict allKeys] count] > [indexPath row])
{
self.detailController.title =
[[dict allKeys] objectAtIndex:[indexPath row]];
} else {
self.detailController.title = #"Here's a problem";
}
Did you implement these UITableView delegate methods ? All these are needed. Also can you post more detailed StackTrace.
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
return [resultSet count];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 280.0;
}
I have a NSURL request that brings back an array of "name" and "phone", "etc"... The "name" Key shows up fine on the master table, but I'm having trouble figuring out how to get the rest of the array to show up on the detail table when I select the row. (I have the DetailerTableViewController working to accept the view). Any help would be appreciated.
Thanks,
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [rowsArray count];
NSLog(#"row count: %#",[rowsArray count]);
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
NSDictionary *dict = [rowsArray objectAtIndex: indexPath.row];
cell.textLabel.text = [dict objectForKey:#"name"];
cell.detailTextLabel.text = [dict objectForKey:#"loginName"];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationController.navigationBar.tintColor = [UIColor colorWithRed:0.0/255.0 green:207.0/255.0 blue:255.0/255.0 alpha:1.0];
self.title = NSLocalizedString(#"Master", #"Master");
NSURL *url = [NSURL URLWithString:#"http://10.0.1.8/~imac/iphone/jsontest.php"];
NSString *jsonreturn = [[NSString alloc] initWithContentsOfURL:url];
NSLog(jsonreturn); // Look at the console and you can see what the results are
NSData *jsonData = [jsonreturn dataUsingEncoding:NSUTF32BigEndianStringEncoding];
NSError *error = nil;
// In "real" code you should surround this with try and catch
NSDictionary * dict = [[CJSONDeserializer deserializer] deserializeAsDictionary:jsonData error:&error];
if (dict)
{
rowsArray = [dict objectForKey:#"member"];
[rowsArray retain];
}
NSLog(#"Array: %#",rowsArray);
NSLog(#"count is: %i", [self.rowsArray count]);
[jsonreturn release];
}
You need to implement:
- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
to handle row selection and to push the view controller for the detail view.