I'm trying to create an application with a UITableView and when selection a row going to another view that containing a UIWebView that will load some website(passing in the row). but i still got this log :
Unknown scheme, doing nothing:
My code is below :
// RootViewController.h
#import <UIKit/UIKit.h>
#interface RootViewController : UITableViewController {
NSArray *books;
NSArray *sites;
NSArray *contacts;
}
// RootViewController.m
#import "RootViewController.h"
#import "SitesViewController.h"
#implementation RootViewController
- (void)viewDidLoad
{
// Setting the main screen title
self.title = #"Main App Screen";
// Retreiving data from the plist file
NSString *file = [[NSBundle mainBundle] pathForResource:#"Data" ofType:#"plist"];
NSDictionary *dict = [[[NSDictionary alloc] initWithContentsOfFile:file] autorelease];
sites = [[NSArray alloc] initWithArray:[dict objectForKey:#"Sites"]];
contacts = [[NSArray alloc] initWithArray:[dict objectForKey:#"Contacts"]];
books = [[NSArray alloc] initWithArray:[dict objectForKey:#"Books"]];
[super viewDidLoad];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// We have 3 sections
return 3;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Returning the number of rows
return numberOfrows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// Returning each cell
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
// section title
return title;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Handling sites section
if (indexPath.section == 0) {
SitesViewController *sitesViewController = [[SitesViewController alloc] initWithNibName:#"SitesViewController" bundle:nil];
// We want to load some data here
sitesViewController.websiteUrl = [sites objectAtIndex:indexPath.row];
// Load this view
[self.navigationController pushViewController:sitesViewController animated:YES];
// Release it
[sitesViewController release];
}
}
// SitesViewController.h
#import <UIKit/UIKit.h>
#interface SitesViewController : UIViewController {
IBOutlet UIWebView *website;
NSString *websiteUrl;
}
#property (nonatomic, retain) IBOutlet UIWebView *website;
#property (nonatomic, retain) NSString *websiteUrl;
#end
// SitesViewController.m
#import "SitesViewController.h"
#implementation SitesViewController
- (void)viewDidLoad
{
[super viewDidLoad];
//[website setDelegate:self];
// Do any additional setup after loading the view from its nib.
NSURL *url = [[NSURL alloc] initWithString:websiteUrl];
[website loadRequest:[NSURLRequest requestWithURL:url]];
[url release];
}
....
#end
As requested the Data.plist file contain this data :
<?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">
<dict>
<key>Sites</key>
<array>
<string>www.freebsd.com</string>
<string>www.kernel.org</string>
<string>www.developer.apple.com</string>
<string>www.github.com</string>
</array>
<key>Contacts</key>
<array>
<string>user#apple.com</string>
<string>user#kernel.org</string>
<string>user#gmail.com</string>
</array>
<key>Books</key>
<array>
<string>book1</string>
<string>book2</string>
<string>book3</string>
</array>
</dict>
</plist>
Thanks for the help.
You will need to add http:// to those urls. They aren't automatically prepended with it.
Related
Can anyone help me to solve the problem. I would like to develop my app using property list with nsobject. When run the app, there is no error but the data from bnm.plist did not load on uitableview.
Below is ViewController.m
#import "MCWViewController.h"
#import "MCWPlacesDetailViewController.h"
#import "MCWPlaces.h"
#interface MCWViewController ()
#end
#implementation MCWViewController {
NSArray *places;
}
#synthesize tableView = _tableView;
- (void)viewDidLoad
{
[super viewDidLoad];
// Initialize table data
// Find out the path of bnm.plist
NSString *path = [[NSBundle mainBundle] pathForResource:#"bnm" ofType:#"plist"];
// Load the file content and read the data into arrays
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:path];
MCWPlaces *placeGO = [MCWPlaces new];
placeGO.name = [dict objectForKey:#"PlaceName"];
placeGO.info = [dict objectForKey:#"PlaceInfo"];
places = [NSArray arrayWithObject:placeGO];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [places count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"PlacesCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
NSLog(#"PlacesCell");
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
MCWPlaces *place = [places objectAtIndex:indexPath.row];
cell.textLabel.text = place.name;
return cell;
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"showPlaceDetails"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
MCWPlacesDetailViewController *destViewController = segue.destinationViewController;
destViewController.place = [places objectAtIndex:indexPath.row];
}
}
Below is Places.h
#import <Foundation/Foundation.h>
#interface MCWPlaces : NSObject
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) NSString *info;
#end
Below is Places.m
#import "MCWPlaces.h"
#implementation MCWPlaces
#synthesize name;
#synthesize info;
#end
Below is Details.m
#import "MCWPlacesDetailViewController.h"
#interface MCWPlacesDetailViewController ()
#end
#implementation MCWPlacesDetailViewController
#synthesize placeInfo;
#synthesize place;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.title = place.name;
self.placeInfo.text = place.info;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Below is Details.h
#import <UIKit/UIKit.h>
#import "MCWPlaces.h"
#interface MCWPlacesDetailViewController : UIViewController
#property (weak, nonatomic) IBOutlet UILabel *placeInfo;
#property (nonatomic, strong) MCWPlaces *place;
#end
bnm.plist
<plist version="1.0">
<dict>
<key>PlaceName</key>
<array>
<string>Place 1</string>
<string>Place 2</string>
<string>Place 3</string>
</array>
<key>PlaceInfo</key>
<array>
<string>Place 1 Info</string>
<string>Place 2 Info</string>
<string>Place 3 Info</string>
</array>
</dict>
</plist>
Did something wrong in my code?
I think my problem is 'cellForRowAtIndexPath' and i have declared 'name' and 'info' as nsstring on Places.h. but on plist is as nsarray. but i dont know how to solve the problem.
Ok so you are in the wrong way.
Use the following code and replace it in your project :
bnm.plist
<?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>PlaceName</key>
<string>Place 1</string>
<key>PlaceInfo</key>
<string>Place 1 Info</string>
</dict>
<dict>
<key>PlaceName</key>
<string>Place 2</string>
<key>PlaceInfo</key>
<string>Place 2 Info</string>
</dict>
</array>
</plist>
MCWPlaces.h
#interface MCWPlaces : NSObject
#property (nonatomic, strong) NSString *name;
#property (nonatomic, strong) NSString *info;
#end
MCWPlaces.m
#import "MCWPlaces.h"
#implementation MCWPlaces
#synthesize name;
#synthesize info;
#end
MCWViewController.m
#import "MCWViewController.h"
#import "MCWPlaces.h"
#define KEY_PLACE_NAME #"PlaceName"
#define KEY_PLACE_INFO #"PlaceInfo"
#interface MCWViewController ()
#property (nonatomic, weak) IBOutlet UITableView *tableView;
#property (nonatomic, strong) NSMutableArray *places;
#end
#implementation MCWViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Init place array
_places = [NSMutableArray array];
// Find out the path of bnm.plist
NSArray *data = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"bnm" ofType:#"plist"]];
NSLog(#"%#", data);
for (NSInteger i = 0; i < data.count; i++)
{
MCWPlaces *placeGO = [MCWPlaces new];
placeGO.name = [[data objectAtIndex:i] objectForKey:KEY_PLACE_NAME];
placeGO.info = [[data objectAtIndex:i] objectForKey:KEY_PLACE_INFO];
[_places addObject:placeGO];
}
NSLog(#"%#", _places);
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _places.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"PlacesCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
NSLog(#"PlacesCell");
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:simpleTableIdentifier];
}
NSLog(#"%#", [_places objectAtIndex:indexPath.row]);
cell.textLabel.text = [[_places objectAtIndex:indexPath.row] name];
return cell;
}
#end
I think you have a problem when you load your data.
Firstly you say you get data from place.plist but in your viewDidLoad you tried to load data from bnm.plist
Try to use the following code :
- (void)viewDidLoad
{
[super viewDidLoad];
// Initialize table data
// Find out the path of bnm.plist
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"bnm" ofType:#"plist"]];
// Load the file content and read the data into arrays
MCWPlaces *placeGO = [MCWPlaces new];
placeGO.name = [dict objectForKey:#"PlaceName"];
placeGO.info = [dict objectForKey:#"PlaceInfo"];
}
Could you show us your bnm.plist ?
I have a Sectioned Tableview sourced from a pList which I want to drill down into children sub views. My only problem is I'm stuck on getting it to populate after first drill down (Entree is the only one with content), "Description" and "Title".
pList
<?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>Rows</key>
<array>
<dict>
<key>Title</key>
<string>Entree</string>
<key>Children</key>
<array>
<dict>
<key>Title</key>
<string>Garlic Bread</string>
<key>Description</key>
<string>Cottage loaf smeared with garlic butter and herbs</string>
<key>Price</key>
<string>8.0</string>
</dict>
<dict>
<key>Title</key>
<string>Bruschetta</string>
<key>Description</key>
<string>Veggies n shit on toast</string>
<key>Price</key>
<string>9.0</string>
</dict>
</array>
</dict>
<dict>
<key>Title</key>
<string>Mains</string>
</dict>
<dict>
<key>Title</key>
<string>Dessert</string>
</dict>
<dict>
<key>Title</key>
<string>Sides</string>
</dict>
</array>
<key>Title</key>
<string>Eat</string>
</dict>
<dict>
<key>Title</key>
<string>Drink</string>
<key>Rows</key>
<array>
<dict>
<key>Title</key>
<string>Red</string>
</dict>
</array>
</dict>
</array>
</plist>
MenuViewController.h
#import <UIKit/UIKit.h>
#interface MenuViewController : UITableViewController {
NSArray *tableDataSource;
NSString *CurrentTitle;
NSInteger CurrentLevel;
}
#property (nonatomic, retain) NSArray *tableDataSource;
#property (nonatomic, retain) NSString *CurrentTitle;
#property (nonatomic, readwrite) NSInteger CurrentLevel;
#end
MenuViewController.m
#import "MenuViewController.h"
#implementation MenuViewController
#synthesize tableDataSource;
#synthesize CurrentLevel, CurrentTitle;
- (void)viewDidLoad
{
[super viewDidLoad];
if(CurrentLevel == 0) {
self.tableDataSource = [NSArray arrayWithContentsOfFile: [[NSBundle mainBundle] pathForResource: #"MenuData" ofType: #"plist"]];
self.navigationItem.title = #"Menu";
}
else
self.navigationItem.title = CurrentTitle;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
return [tableDataSource count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
return [[[tableDataSource objectAtIndex: section]
objectForKey: #"Rows"] count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [[tableDataSource objectAtIndex: section]
objectForKey: #"Title"];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSDictionary *dictionary = [[[self.tableDataSource objectAtIndex: indexPath.section] objectForKey: #"Rows"] objectAtIndex: indexPath.row];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
*//The problem is right here, im just stuck on how to access this property correctly
**cell.textLabel.text = [dictionary objectForKey:#"Title"];***
// Configure the cell...
return cell;
}
/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
*/
/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the item to be re-orderable.
return YES;
}
*/
#pragma mark - Table view delegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
// Navigation logic may go here. Create and push another view controller.
/*
<#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:#"<#Nib name#>" bundle:nil];
// ...
// Pass the selected object to the new view controller.
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
*/
NSDictionary *dictionary = [[[self.tableDataSource objectAtIndex: indexPath.section] objectForKey: #"Rows"] objectAtIndex: indexPath.row];
//Get the children of the present item.
NSArray *Children = [dictionary objectForKey:#"Children"];
if([Children count] == 0) {
MenuDetailViewController *mdvController = [[MenuDetailViewController alloc] initWithNibName:#"MenuDetailView" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:mdvController animated:YES];
[mdvController release];
}
else {
//Prepare to tableview.
MenuViewController *mvController = [[MenuViewController alloc] initWithNibName:#"MenuViewController" bundle:[NSBundle mainBundle]];
//Increment the Current View
mvController.CurrentLevel += 1;
//Set the title;
mvController.CurrentTitle = [dictionary objectForKey:#"Title"];
//Push the new table view on the stack
[self.navigationController pushViewController:mvController animated:YES];
mvController.tableDataSource = Children;
[mvController release];
}
}
#end
You can drill data in recursive manner.
For root view controller cell selection method
you have to modify your code as
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if(self.currentLevel=0)
return [tableDataSource count];
else
return 1;//You require only one section in later levels
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if(self.currentLevel=0)
return [[[tableDataSource objectAtIndex: section] objectForKey: #"Rows"] count];
else
return [tableDataSource count];// Number of children
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if(self.currentLevel=0)
return [[tableDataSource objectAtIndex: section] objectForKey: #"Title"];
else
return self.title;//Or your custom title
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSDictionary *dictionary = nil;
if(self.currentLevel=0)
dictionary= [[[self.tableDataSource objectAtIndex: indexPath.section] objectForKey: #"Rows"] objectAtIndex: indexPath.row];
else
dictionary = [self.tableDataSource objectAtIndex: indexPath.row];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
cell.textLabel.text = [dictionary objectForKey:#"Title"];
// Configure the cell...
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if(self.currentLevel=0)
dictionary= [[[self.tableDataSource objectAtIndex: indexPath.section] objectForKey: #"Rows"] objectAtIndex: indexPath.row];
else
dictionary = [self.tableDataSource objectAtIndex: indexPath.row];
if([dictionary objectForKey:#"Children"]!=nil){
//Drill down only if you have child
//Now drilling down logic
id Object = [dictionary objectForKey:#"Children"];
NSString * title = [dictionary objectForKey:#"Title"];
if([object isKindOfClass:[NSArray class]) {
NSArray * dataSource = (NSArray *)object;
MenuViewController * viewController = [[MenuViewController alloc] initWithNibName:#"YourNibName" bundleNameOrNil:nil];
viewController.title = title;
viewController.tableDataSource = dataSource;
viewController.currentLevel = self.currentLevel+1;
[self.navigationController pushViewController:viewController animated:YES];
[viewController release];
} else if([object isKindOfClass:[NSDictionary class]) {
//Only one child in the form of dictionary
//Initialize your detail view controller and push to nav stack
YourDetailViewController * viewController = [[YourDetailViewController alloc] initWithNibName:#"YourNibName" bundleNameOrNil:nil];
viewController.data = (NSDictionary*)object;//Pass the view data(price etc)
viewController.currentLevel = self.currentLevel+1;
[self.navigationController pushViewController:viewController animated:YES];
[viewController release];
} else {
//Error drilling down is not possible
}
}
}
Hope this will sort out your drilling problem.. :)
I'm having trouble finding a easy to understand tutorial on having a sectioned UITableView which gets its data from a pList file.
Things im having trouble with, is how to properly structure the pList file to cater for 2 different sections.
The root of the plist should be an array. The array should contain two dictionaries (your sections). The dictionaries will contain two keys: one for section title and one for the rows in the section.
Assuming you read your plist into an NSArray* sections, you can return the section, row count, section title and cell titles using the code below.
Your plist file would look like this:
<?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>Section1</string>
<key>Rows</key>
<array>
<string>Section1 Item1</string>
<string>Section1 Item2</string>
</array>
</dict>
<dict>
<key>Title</key>
<string>Section2</string>
<key>Rows</key>
<array>
<string>Section2 Item1</string>
<string>Section2 Item2</string>
</array>
</dict>
</array>
</plist>
#import "RootViewController.h"
#interface RootViewController ()
#property (copy, nonatomic) NSArray* tableData;
#end
#implementation RootViewController
#synthesize tableData;
- (void) dealloc
{
self.tableData = nil;
[super dealloc];
}
- (void) viewDidLoad
{
[super viewDidLoad];
self.tableData = [NSArray arrayWithContentsOfFile: [[NSBundle mainBundle] pathForResource: #"Table" ofType: #"plist"]];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;
{
return [tableData count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;
{
return [[[tableData objectAtIndex: section] objectForKey: #"Rows"] count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;
{
return [[tableData objectAtIndex: section] objectForKey: #"Title"];
}
- (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 = [[[tableData objectAtIndex: indexPath.section] objectForKey: #"Rows"] objectAtIndex: indexPath.row];
return cell;
}
#end
I have an array of dictionaries in an iOS .plist structured similar to the following:
<plist version="1.0">
<array>
<dict>
<key>name</key>
<string>Afghanistan</string>
<key>government</key>
<string>Islamic Republic</string>
<key>population</key>
<integer>29121286
</integer>
</dict>
<dict>
<key>name</key>
<string>Albania</string>
<key>government</key>
<string>Emerging Democracy</string>
<key>population</key>
<integer>2986952</integer>
</dict>
I am trying to load the <key>name</key> from each dictionary into an NSTableViewCell then display them all alphabetically in an NSTableView similar to the Contacts App in iOS.
Below are my ViewControllers .h and .m. The sort is working, but I am not able to load the results into the TableViewCells?
FirstViewController.h
#import <UIKit/UIKit.h>
#interface FirstViewController : UIViewController <UITableViewDelegate,UITableViewDataSource>
{
NSArray *sortedCountries;
}
#property (nonatomic, retain) NSArray *sortedCountries;
#end
FirstViewController.m
#import "FirstViewController.h"
#implementation FirstViewController
#synthesize sortedCountries;
-(void)viewDidLoad {
NSString *path = [[NSBundle mainBundle] pathForResource:#"countries"ofType:#"plist"];
NSArray *countries = [NSArray arrayWithContentsOfFile:path];
NSSortDescriptor *descriptor = [[[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES] autorelease];
NSArray *sortedCountries = [[countries sortedArrayUsingDescriptors:[NSArray arrayWithObject:descriptor]] retain];
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
-(NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return 2;
}
-(UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *country = [sortedCountries objectAtIndex:indexPath.row];
NSString *countryName = [country objectForKey:#"name"];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = countryName;
return cell;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[sortedCountries release];
[super dealloc];
}
#end
EDIT: Another question related to this here.
Add an ivar to your view controller's #interface in the header file:
#interface MyViewController : UITableViewController
{
...
NSArray *sortedCountries;
}
Add this code (to read and sort the plist by country name) to your view controller's initWith... method:
NSArray *countries = [NSArray arrayWithContentsOfFile: pathToPlist];
// Now the array holds NSDictionaries, sort 'em:
NSSortDescriptor *descriptor = [[[NSSortDescriptor alloc] initWithKey:#"name" ascending:YES] autorelease];
sortedCountries = [[countries sortedArrayUsingDescriptors:[NSArray arrayWithObject:descriptor]] retain];
Then use the following snippet to extract the values:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *country = [sortedCountries objectAtIndex:indexPath.row];
NSString *countryName = [country objectForKey:#"name"];
NSString *governmentType = [country objectForKey:#"government"];
NSSInteger population = [[country objectForKey:#"population"] integerValue];
// ... do something with countryName, governmentType, population
}
Don't forget to release sortedCountries:
- (void)dealloc
{
...
[sortedCountries release];
[super dealloc];
}
Create an NSArray for your file:
NSArray *iOSPlist = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"iOS" ofType:#"plist"]];
then in this method write after if (cell == nil){
}:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
cell.textLabel.text = [[iOSPlist objectAtIndex:indexPath.row] objectForKey:#"name"];
}
and don't forget to return [iOSPlist count] in the - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section method;
Here is an example pulling the version number out of the info.plist. Use something similar to pull out your name key ( objectForKey:#"name")
NSString *path = [[NSBundle mainBundle] bundlePath];
NSString *finalPath = [path stringByAppendingPathComponent:#"Info.plist"];
plist = [[NSDictionary dictionaryWithContentsOfFile:finalPath] retain];
NSString* version = [plist objectForKey:#"CFBundleVersion"];
Here's a StackOverflow question on working with data in plists. The answers get quite detailed.
Parse Plist (NSString) into NSDictionary
I have made some progress and am editing the question to be current again. My big issue now is that the grouped table view will load, but shows all of everything in each section with each row. Also, my UIAlertView is returning all references to my plist (null). How would I fix this because the references to the plist are killing me. Any and all help would be greatly appreciated!
Here is the plain text version of my plist file:
<array>
<dict>
<key>eventName</key>
<string>Comedy Caravan</string>
<key>eventSpecifics</key>
<string>Nicholas Anthony</string>
<key>eventLocation</key>
<string>The Cats Den</string>
<key>eventType</key>
<string>Comedy</string>
<key>eventGoodies</key>
<string>Both</string>
<key>eventDate</key>
<date>2010-07-23T00:00:00Z</date>
</dict>
<dict>
<key>eventName</key>
<string>Comedy Caravan</string>
<key>eventLocation</key>
<string>The Cats Den</string>
<key>eventType</key>
<string>Comedy</string>
<key>eventSpecifics</key>
<string>Bruce Baum</string>
<key>eventGoodies</key>
<string>Prizes</string>
<key>eventDate</key>
<date>2010-07-24T00:00:00Z</date>
</dict>
<dict>
<key>eventName</key>
<string>Late Night Film Series</string>
<key>eventLocation</key>
<string>The Cats Den</string>
<key>eventType</key>
<string>Comedy</string>
<key>eventSpecifics</key>
<string>Avatar</string>
<key>eventGoodies</key>
<string>Food</string>
<key>eventDate</key>
<date>2010-07-24T02:00:00Z</date>
</dict>
</array>
Here is my ThisWeekViewController.h:
#import <UIKit/UIKit.h>
#class Event;
#interface ThisWeekViewController : UITableViewController
{
NSArray *eventNames;
Event *event;
}
#property (nonatomic, retain) NSArray *eventNames;
#property (nonatomic, retain) Event *event;
#end
and Here is my ThisWeekViewController.m:
#import "ThisWeekViewController.h"
#import "Event.h"
#implementation ThisWeekViewController
#synthesize eventNames;
#synthesize event;
- (void)viewDidLoad {
[super viewDidLoad];
NSString *path = [[NSBundle mainBundle] pathForResource:#"Events" ofType:#"plist"];
NSArray *dict = [[NSArray alloc] initWithContentsOfFile:path];
NSArray *namesArray = [dict valueForKey:#"eventName"];
self.eventNames = namesArray;
[dict release];
[self.tableView reloadData];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
self.eventNames = nil;
}
#pragma mark Table View Methods
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [self.eventNames count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSString *key = [NSString stringWithFormat:#"%#", event.eventName];
return key;
}
// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.eventNames count];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
NSUInteger row = [indexPath row];
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
// Set the cell's text to the event name
cell.textLabel.text = event.eventName;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
}
- (void)dealloc {
// [thisWeek release];
[event release];
[eventNames release];
[super dealloc];
}
#end
I have also included my Event.h file
#import <Foundation/Foundation.h>
#interface Event : NSObject {
NSString *eventName;
NSString *eventType;
NSDate *eventDate;
NSString *eventLocation;
NSString *eventGoodies;
NSString *eventSpecifics;
}
- (id)initWithDictionary:(NSDictionary *)aDictionary;
#property (nonatomic, retain) NSString *eventName;
#property (nonatomic, retain) NSString *eventType;
#property (nonatomic, retain) NSString *eventLocation;
#property (nonatomic, retain) NSDate *eventDate;
#property (nonatomic, retain) NSString *eventGoodies;
#property (nonatomic, retain) NSString *eventSpecifics;
#end
and my Event.m file
#import "Event.h"
#implementation Event
#synthesize eventName;
#synthesize eventType;
#synthesize eventDate;
#synthesize eventLocation;
#synthesize eventGoodies;
#synthesize eventSpecifics;
- (id)initWithDictionary:(NSDictionary *)aDictionary {
if ([self init]) {
self.eventName = [aDictionary valueForKey:#"eventName"];
self.eventType = [aDictionary valueForKey:#"eventType"];
self.eventDate = [aDictionary valueForKey:#"eventDate"];
self.eventLocation = [aDictionary valueForKey:#"eventLocation"];
self.eventGoodies = [aDictionary valueForKey:#"eventGoodies"];
self.eventSpecifics = [aDictionary valueForKey:#"eventSpecifics"];
}
return self;
}
- (void)dealloc {
[eventName release];
[eventType release];
[eventDate release];
[eventLocation release];
[eventGoodies release];
[eventSpecifics release];
[super dealloc];
}
#end
I would like to be able to place things such as cell.detailTextLabel.text = event.eventSpecifics and just run off of references like that.
If I recall correctly, UITableViewController reloads the table view in -viewWillAppear:. This may very well be called before -viewDidLoad is called. I would recommend that you insert a call to [self.tableView reloadData] at the end of your implementation of -viewDidLoad.
You should also be calling [super viewDidLoad] at the top of your implementation of -viewDidLoad, and similarly for -viewDidUnload.
Also, you don't need to declare your class as conforming to UITableViewDataSource or UITableViewDelegate as your superclass (UITableViewController) already does that for you.