Loading an html files to a web view - iphone

I have a table view with a lot of items
when i click on a cell in the table it loads a view with a web view outlet, in the web view in viewdidload i have this line of code to load the html file wich is in the project file
NSString *name = pagename.text;
[WebView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:name ofType:#"html"]isDirectory:NO]]];
the code to push from the selected cell to that web view with is called Test is
if (indexPath.row == 0)
{
Test *test = [[Test alloc] initWithNibName:nil bundle:nil];
test.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:test animated:YES];
NSString *name1 = #"ba";
[[test pagename] setText:[NSString stringWithString:(NSString *)name1]];
}
else if (indexPath.row == 1)
{
Test *test = [[Test alloc] initWithNibName:nil bundle:nil];
test.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:test animated:YES];
NSString *name1 = #"bb";
[[test pagename] setText:[NSString stringWithString:(NSString *)name1]];
}
else if (indexPath.row == 2)
{
Test *test = [[Test alloc] initWithNibName:nil bundle:nil];
test.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:test animated:YES];
NSString *name1 = #"bc";
[[test pagename] setText:[NSString stringWithString:(NSString *)name1]];
}
the html files are called ba,bb,bc and bd .html
the problem is when i select any cell of the four cells i have in the table it shows the same html file "ba.html"
i tried everything , cleaning the project, deleting the files and copying them back, changed the simulator, restarted the lap and even changed the files names.
any help ?
thanks in advance
update :
This is the hole code
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [array count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CustomCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
[[cell textLabel] setTextAlignment:UITextAlignmentRight];
cell.textLabel.text = [array objectAtIndex:indexPath.row];
cell.textLabel.font = [UIFont systemFontOfSize:18];
cell.textLabel.numberOfLines = 3;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[tableView deselectRowAtIndexPath:indexPath animated:YES];
if (indexPath.row == 0)
{
Test *test = [[Test alloc] initWithNibName:nil bundle:nil];
test.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:test animated:YES];
NSString *name1 = #"ba";
[[test pagename] setText:name1];
}
else if (indexPath.row == 1)
{
Test *test = [[Test alloc] initWithNibName:nil bundle:nil];
test.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:test animated:YES];
NSString *name1 = #"bb";
[[test pagename] setText:name1];
}
else if (indexPath.row == 2)
{
Test *test = [[Test alloc] initWithNibName:nil bundle:nil];
test.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:test animated:YES];
NSString *name1 = #"bc";
[[test pagename] setText:name1];
}
else if (indexPath.row == 3)
{
Test *test = [[Test alloc] initWithNibName:nil bundle:nil];
test.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:test animated:YES];
NSString *name1 = #"bd";
[[test pagename] setText:name1];
}
}

You are presenting the controller before setting the page.
Make 'name' an NSString instance variable in your webview class. Make it a property (nonatomic,retain) and synthesize it.
Instead of setting the viewcontroller's label, set name.
Then in viewDidLoad, set the label from name.
Set the label from the name, not the other way around.
In the cell was selected:
Test *test = [[Test alloc] initWithNibName:nil bundle:nil];
test.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
NSString *name1 = #"bc";
[test setName:[NSString stringWithString:(NSString *)name1]];
[self presentModalViewController:test animated:YES];
In the Web view viewdidload
-(void)viewDidLoad {
pagename.text = self.name;
[WebView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:name ofType:#"html"]isDirectory:NO]]];
}

Can you put a breakpoint or a log to see if indexPath.row is always 0?
If this is the case, then maybe your table is created in a way that each element is in its own section. You would then have to use indexPath.section as each object would be row 0 of its own section.
Also, I do not know which type of object is 'pagename' but setters generally retain the parameters, so you do not have to create a copy of name1 in
[[test pagename] setText:[NSString stringWithString:(NSString *)name1]];
Note: this really depends on how the property is declared in the class, but typically, those type of properties are retained.

Related

How to send data to a detail vc from callOutAccessoryControlTapped: method

I'm using the didSelectRowAtIndexPath: to pass some data from a table vc to a detail vc using the code below that works fine.
What I'm trying to do is to also send this data from a map callOutAccessoryControlTapped: method but I am unsure how to send the data that way.
How would I send
detailViewController.descriptionTextViewString = [[publicDataArray objectAtIndex:indexPath.row] objectForKey:#"short_description"];
using the
callOutAccessoryControlTapped: method?
The objectAtIndex:indexPath.row is unrecognized from within the map callOutAccessoryControlTapped: method.
Here's my didSelectRowAtIndexPath: code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
ScrollView_ExampleViewController *detailViewController = [[ScrollView_ExampleViewController alloc] initWithNibName:#"DetailViewController" bundle:nil];
detailViewController.latStr = [[[publicDataArray objectAtIndex:indexPath.row] objectForKey:#"address"] objectForKey:#"lat"];
detailViewController.lngStr = [[[publicDataArray objectAtIndex:indexPath.row] objectForKey:#"address"] objectForKey:#"lng"];
detailViewController.addressStr = [[[publicDataArray objectAtIndex:indexPath.row] objectForKey:#"address"] objectForKey:#"address"];
detailViewController.titleStr = [[publicDataArray objectAtIndex:indexPath.row] objectForKey:#"title"];
detailViewController.mainImageUrl = [[publicDataArray objectAtIndex:indexPath.row] objectForKey:#"image"];
detailViewController.listingId = [[publicDataArray objectAtIndex:indexPath.row] objectForKey:#"id"];
detailViewController.descriptionTextViewString = [[publicDataArray objectAtIndex:indexPath.row] objectForKey:#"short_description"];
[self.navigationController pushViewController:detailViewController animated:YES];
}
Here's my map annotation calloutAccessoryControlTapped: method
- (void)mapView:(MKMapView *)mv annotationView:(MKAnnotationView *)pin calloutAccessoryControlTapped:(UIControl *)control {
ScrollView_ExampleViewController *detailViewController = [[ScrollView_ExampleViewController alloc] initWithNibName:#"ScrollView_ExampleViewController" bundle:nil];
MyAnnotation *theAnnotation = (MyAnnotation *) pin.annotation;
detailViewController.titleStr = theAnnotation.title;
detailViewController.addressStr = theAnnotation.subtitle;
// detailViewController.latStr = theAnnotation.latString;
// detailViewController.lngStr = theAnnotation.lngString;
// detailViewController.url = theAnnotation.theUrl;
[self.navigationController pushViewController:detailViewController animated:YES];
}
You can use the following method to get the tableView's selected index:
NSIndexPath *selectedIndexPath = [tableView indexPathForSelectedRow];

TableView not getting hidden in didSelectRowAtIndexPath in xcode?

I m fairly new to objective-C and implementing the concept of autocomplete feature for a UItextField.I can do it appropriately .but when I select a particular cell then that cell's text should be displayed in UITextField and correspondingly tableView must be hidden.But Im unable to hide a UITableView after selecting a cell..Where I m going wrong?
- (void)searchAutocompleteEntriesWithSubstring:(NSString *)substring {
NSURL *urlString= [NSString stringWithFormat:#"http://179.87.89.90/services/Service.svc/GetCities/?p=%#&k=%#",substring,txtId.text];
NSURL *jsonUrl =[NSURL URLWithString:urlString];
NSString *jsonStr = [[NSString alloc] initWithContentsOfURL:jsonUrl];
parser = [[NSXMLParser alloc] initWithContentsOfURL:jsonUrl];
currentHTMLElement=#"3";
[parser setDelegate:self];
[parser setShouldProcessNamespaces:NO];
[parser setShouldReportNamespacePrefixes:NO];
[parser setShouldResolveExternalEntities:NO];
[parser parse];
[parser release];
NSLog(#"%#",arr2);
if([arr2 count]!=0)
{
self.autocompleteUrls = [[NSMutableArray alloc] init];
autocompleteTableView = [[UITableView alloc] initWithFrame:CGRectMake(88, 447, 200, 120) style:UITableViewStyleGrouped];
autocompleteTableView.delegate = self;
autocompleteTableView.dataSource = self;
autocompleteTableView.scrollEnabled = YES;
// autocompleteTableView.hidden = YES;
[self.view addSubview:autocompleteTableView];
[autocompleteUrls removeAllObjects];
for(int i=0;i<[arr2 count];i++)
{
NSString *curString = [[arr2 objectAtIndex:i] valueForKey:#"Name"];
NSRange substringRange = [curString rangeOfString:substring];
if (substringRange.location == 0)
[autocompleteUrls addObject:curString];
}
[autocompleteTableView reloadData];
}
else
{
autocompleteTableView.delegate=nil;
autocompleteTableView.dataSource=nil;
autocompleteTableView.hidden = YES;
}
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
if( textField == txtcity)
{
autocompleteTableView.hidden = NO;
NSString *substring = [NSString stringWithString:textField.text];
substring = [substring stringByReplacingCharactersInRange:range withString:string];
[self searchAutocompleteEntriesWithSubstring:substring];
return YES;
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger) section {
return autocompleteUrls.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
static NSString *AutoCompleteRowIdentifier = #"AutoCompleteRowIdentifier";
cell = [tableView dequeueReusableCellWithIdentifier:AutoCompleteRowIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault reuseIdentifier:AutoCompleteRowIdentifier] autorelease];
}
cell.textLabel.text = [autocompleteUrls objectAtIndex:indexPath.row];
cell.textLabel.font=[UIFont boldSystemFontOfSize:12];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
txtcity.text = selectedCell.textLabel.text;
[autocompleteUrls removeAllObjects];
[self.autocompleteTableView setHidden:YES];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath];
txtcity.text = selectedCell.textLabel.text;
[autocompleteUrls removeAllObjects];
autocompleteTableView.hidden=YES;
}
How can I hide autocompleteTableView after selecting a row ?
Any help would be appreciated..
The issue is with the if condition, when the if is evaluated true then again the autocompleteTableView is again allocated and added to self.view. It'll be placed over the previous tableView and youare losing the reference of previous tableView. If you call autocompleteTableView.hidden = YES. Last added tableView will be hidden. But previously added tableViews will be there.
Just change the if block like:
if([arr2 count]!=0)
{
self.autocompleteUrls = [[NSMutableArray alloc] init];
if(autocompleteTableView)
[autocompleteTableView removeFromSuperView];
autocompleteTableView = [[UITableView alloc] initWithFrame:CGRectMake(88, 447, 200, 120) style:UITableViewStyleGrouped];
autocompleteTableView.delegate = self;
autocompleteTableView.dataSource = self;
autocompleteTableView.scrollEnabled = YES;
// autocompleteTableView.hidden = YES;
[self.view addSubview:autocompleteTableView];
for(int i=0;i<[arr2 count];i++)
{
NSString *curString = [[arr2 objectAtIndex:i] valueForKey:#"Name"];
NSRange substringRange = [curString rangeOfString:substring];
if (substringRange.location == 0)
[autocompleteUrls addObject:curString];
}
[autocompleteTableView reloadData];
}
#Arizah - please try making a fresh app to test the UItableview & UItextField delegate methods. It might be that somewhere --
autocompleteTableView.delegate=nil;
autocompleteTableView.dataSource=nil;
gets called due to which further no delegate method like :
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
WILL NOT BE CALLED. TRY AVOIDING THIS CODE.
Also the statement: self.autocompleteUrls = [[NSMutableArray alloc] init];
is technically incorrect since a retain property needs no allocation. Instead you can use:
NSMutableArray *theArray= [[NSMutableArray alloc] init];
self.autocompleteUrls = theArray;
[theArray release];
did you try:
[self.tableView setHidden:YES];

Just cannot figure out how to reloadData in UITableView using a navigationController

This is my first time asking a question & posting code so I hope I have included everything that is necessary.
In several of my other apps I have been able to successfully reloadData in a UITableView but for some reason I cannot get it to work here.
I am using a navigationController and drilling down a few levels in the UITableView until a new class loads which right now just has two buttons that switch between 2 similar plist files so I can tell that the tableView is actually reloading (Data.plist & Data2.plist)
This is eventually going to be a timesheet sort of app where individual jobs are listed and the user (driver) will punch a timeclock with In/Out buttons. For now, what I want is to drill down and click the button that loads the other plist and go back up to reveal that the new plist data has loaded. My problem is that I cannot get the tableView to reload at all. I've tried putting different variations of [self.tableView reloadData] & [myTableView reloadData] (which I have also connected via IB) all over the place but none of them work. I'm currently calling a method in the rootViewController (where the tableView is) from detailViewController (where the buttons are) and that basic process works for me in other apps when there is no navigationController being used. The navigationController seems to be throwing me off here in this app. I hope an easy solution can be found. My code so far looks like this:
AppDelegate.m
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[window addSubview:[navigationController view]];
[window makeKeyAndVisible];
}
RootViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
//THIS ESTABLISHES WHICH PLIST TO LOAD BASED ON THE BUTTON CLICKED
plistToUse = [[NSUserDefaults standardUserDefaults] objectForKey:#"plistToUse"];
if (plistToUse == #"Data.plist") {
NSString *Path = [[NSBundle mainBundle] bundlePath];
NSString *DataPath = [Path stringByAppendingPathComponent:#"Data.plist"];
NSDictionary *tempDict = [[NSDictionary alloc] initWithContentsOfFile:DataPath];
self.data = tempDict;
[tempDict release];
} else if (plistToUse == #"Data2.plist") {
NSString *Path = [[NSBundle mainBundle] bundlePath];
NSString *DataPath = [Path stringByAppendingPathComponent:#"Data2.plist"];
NSDictionary *tempDict = [[NSDictionary alloc] initWithContentsOfFile:DataPath];
self.data = tempDict;
[tempDict release];
} else {
NSString *Path = [[NSBundle mainBundle] bundlePath];
NSString *DataPath = [Path stringByAppendingPathComponent:#"Data.plist"];
NSDictionary *tempDict = [[NSDictionary alloc] initWithContentsOfFile:DataPath];
self.data = tempDict;
[tempDict release];
}
if(CurrentLevel == 0) {
NSArray *tempArray = [[NSArray alloc] init];
self.tableDataSource = tempArray;
[tempArray release];
self.tableDataSource = [self.data objectForKey:#"Rows"];
self.navigationItem.title = #"Choose Driver";
} else if (CurrentLevel == 1) {
self.navigationItem.title = #"Choose Day";
} else if (CurrentLevel == 2) {
self.navigationItem.title = #"Choose Job";
} else if (CurrentLevel == 3) {
self.navigationItem.title = #"Job Details";
} else {
self.navigationItem.title = CurrentTitle;
}
}
-(void)update {
dvController.labelHelper.text = #"UPDATED"; //USED TO SEE IF A LABEL IN THE BUTTON CLASS WILL UPDATE
NSArray *tempArray = [[NSArray alloc] init];
self.tableDataSource = tempArray;
[tempArray release];
self.tableDataSource = [self.data objectForKey:#"Rows"];
self.navigationController.navigationItem.title = #"Choose Driver";
self.navigationController.title = #"THE TITLE";
[myTableView reloadData];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
unsortedIndex=1;
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.tableDataSource 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] autorelease];
}
dictionary = [self.tableDataSource objectAtIndex:indexPath.row];
cell.textLabel.text = [dictionary objectForKey:#"Title"];
NSArray *Children = [dictionary objectForKey:#"Children"];
if ([Children count] == 0) {
Titles = [dictionary objectForKey:#"Title"];
in1 = [[NSUserDefaults standardUserDefaults] objectForKey:#"InTime1"];
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#", in1];
}
in1 = [[NSUserDefaults standardUserDefaults] objectForKey:#"InTime1"];
out1 = [[NSUserDefaults standardUserDefaults] objectForKey:#"OutTime1"];
cell.detailTextLabel.text = [NSString stringWithFormat:#"%#:%#", in1, out1];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
dictionary = [self.tableDataSource objectAtIndex:indexPath.row];
NSArray *Children = [dictionary objectForKey:#"Children"];
DetailViewController *dvController = [[DetailViewController alloc] initWithNibName:#"DetailView" bundle:[NSBundle mainBundle]];
if([Children count] == 0) {
[self.navigationController pushViewController:dvController animated:YES];
dvController.labelSiteName.text = [dictionary objectForKey:#"Company"];
dvController.labelSiteAddress.text = [dictionary objectForKey:#"Address"];
dvController.labelSiteNotes.text = [dictionary objectForKey:#"Notes"];
[dvController.mapView setMapType:MKMapTypeStandard];
[dvController.mapView setZoomEnabled:YES];
[dvController.mapView setScrollEnabled:YES];
dvController.mapView.showsUserLocation = YES;
[dvController release];
}
else {
RootViewController *rvController = [[RootViewController alloc] initWithNibName:#"RootViewController" bundle:[NSBundle mainBundle]];
rvController.CurrentLevel += 1;
rvController.CurrentTitle = [dictionary objectForKey:#"Title"];
[self.navigationController pushViewController:rvController animated:YES];
rvController.tableDataSource = Children;
[rvController release];
}
}
DetailViewController.m
These are the two buttons that should reload the tableView with either Data.plist or Data2.plist
-(IBAction)getInTime1:(id)sender {
plistToUse = #"Data.plist";
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:plistToUse forKey:#"plistToUse"];
[defaults synchronize];
[rvController update];
}
-(IBAction)getOutTime1:(id)sender {
plistToUse = #"Data2.plist";
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:plistToUse forKey:#"plistToUse"];
[defaults synchronize];
[rvController update];
}
I appreciate any help you can give.
Add your data fetching from plist code into your viewDidAppear or viewWillAppear methods, so that each time view appears, the data is loaded from plist.
And also note that your arrays are allocated only once.
This will work for you.

UIPickerView in Detailview with .PLIST

I've searched the web + stackoverflow for a solution.
I've an UITableView with information from a .plist file. The plist file have childs. Like the image.
plist http://www.afbeeldingenuploaden.nl/uploads/648899Schermafbeelding%202011-06-12%20om%2009.50.28.png
When i go to DetailView it will display information out of an UIPickerView that's included in the view. I want to display information from the child in the pickerview, the last level. Like the image.
plist1 http://www.afbeeldingenuploaden.nl/uploads/740501Schermafbeelding%202011-06-12%20om%2012.03.40.png
The problem is that i can't reach the last level from the plist in the UIPickerview with my code.
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
NSDictionary *dictionary = [tableDataSource objectAtIndex:row];
return [dictionary objectForKey:#"days"];
}
I use in my tableview for the detailview to reach the last level of the plist.
NSString currentLevel
Can anyone help me out with this, i'm stuck.
As I read the plist, it has an array of dictionaries first of which has a dictionary as one of its values at the second array level. Based on that, your method should be,
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
NSDictionary *dictionary = [tableDataSource objectAtIndex:row];
return [[dictionary objectForKey:#"New item"] objectForKey:#"days"];
}
This will work for the plist in the image. However if more members are added they should adhere to the same structure.
- (void)viewDidLoad {
[super viewDidLoad];
NSString *Path = [[NSBundle mainBundle] bundlePath];
NSString *DataPath = [Path stringByAppendingPathComponent:#"Diyet.plist"];
NSDictionary *tempDict = [[NSDictionary alloc] initWithContentsOfFile:DataPath];
self.data = tempDict;
[tempDict release];
NSArray *tempArray = [[NSArray alloc] init];
self.tableDataSource = tempArray;
[tempArray release];
self.tableDataSource = [data objectForKey:#"Bitki"];
pickerView.delegate = self;
pickerView.dataSource = self;
}
- (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];
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
// Configure the cell.
cell.textLabel.text = [[tableDataSource objectAtIndex:indexPath.row] objectForKey:#"name"];
cell.textLabel.numberOfLines = 2;
cell.textLabel.font = [UIFont boldSystemFontOfSize:16];
tableView.scrollEnabled = NO;
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *dictionary = [tableDataSource objectAtIndex:indexPath.row];
NSArray *modelle = [dictionary objectForKey:#"DETAIL"];
if([modelle count] == 0) {
DetailController *dvController = [[DetailController alloc] initWithNibName:#"DetailController" bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:dvController animated:YES];
dvController.names.text = [dictionary objectForKey:#"name"];
} else {
BootViewController *rvController = [[BootViewController alloc] initWithNibName:#"BootViewController" bundle:[NSBundle mainBundle]];
rvController.currentLevel += 1;
rvController.currentTitle = [dictionary objectForKey:#"name"];
[self.navigationController pushViewController:rvController animated:YES];
rvController.tableDataSource = modelle;
[rvController release];
}
}

iphone Dev - activity indicator with NSThread not working on Nav controller table view

I really can't get this to work, basically when my JSON feeds loads I want the indicator to show, then hide when it's stopped.
It loads top level menu items 1st "Publishing, Broadcasting, Marketing Services", then when Broadcasting is selected it loads a feed using the JSON framework hosted on Google. Round this load I call startIndicator and stopIndicator using the NSThread. Have I missed something?
#implementation GeneralNewsTableViewController
#synthesize dataList;
#synthesize generalNewsDetailViewController;
#synthesize atLevel;
-(void) startIndicator
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc ] init ];
[(UIActivityIndicatorView *)[self navigationItem].rightBarButtonItem.customView startAnimating];
[pool release];
}
-(void) stopIndicator
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc ] init ];
[(UIActivityIndicatorView *)[self navigationItem].rightBarButtonItem.customView stopAnimating];
[pool release];
}
- (void)viewDidLoad {
NSMutableArray *checker = self.dataList;
if(checker == nil)
{
self.title = NSLocalizedString(#"General1",#"General News");
NSMutableArray *array = [[NSArray alloc] initWithObjects:#"Publishing", #"Broadcasting",#"Marketing Services",nil];
self.dataList = [array retain];
self.atLevel = #"level1";
[array release];
}
UIActivityIndicatorView * activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
//set the initial property
[activityIndicator stopAnimating];
[activityIndicator hidesWhenStopped];
//Create an instance of Bar button item with custome view which is of activity indicator
UIBarButtonItem * barButton = [[UIBarButtonItem alloc] initWithCustomView:activityIndicator];
//Set the bar button the navigation bar
[self navigationItem].rightBarButtonItem = barButton;
//Memory clean up
[activityIndicator release];
[barButton release];
[super viewDidLoad];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *level = self.atLevel;
if([level isEqualToString:#"level2"])
{
return 70.0f;
}
else
{
return 40.0f;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *FirstLevelCell = #"FirstLevelCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:FirstLevelCell];
if(cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:FirstLevelCell] autorelease];
}
NSInteger row = [indexPath row];
NSString *level = self.atLevel;
if([level isEqualToString:#"level2"])
{
NSMutableArray *stream = [self.dataList objectAtIndex:row];
NSString *newsTitle = [stream valueForKey:#"title"];
if( ![newsTitle isKindOfClass:[NSString class]] )
{
cell.textLabel.text = #"";
}
else
{
cell.textLabel.text = [stream valueForKey:#"title"];
}
cell.textLabel.numberOfLines = 2;
cell.textLabel.font =[UIFont systemFontOfSize:10];
cell.detailTextLabel.numberOfLines = 1;
cell.detailTextLabel.font= [UIFont systemFontOfSize:8];
cell.detailTextLabel.text = [stream valueForKey:#"created"];
NSData *imageURL = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:#"http://www.website.co.uk/images/stories/img.jpg"]];
UIImage *newsImage = [[UIImage alloc] initWithData:imageURL];
cell.imageView.image = newsImage;
[imageURL release];
[newsImage release];
}
else
{
cell.textLabel.text = [dataList objectAtIndex:row];
}
return cell;
}
- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUInteger row = [indexPath row];
NSMutableString *levelType = (NSMutableString *) [dataList objectAtIndex:row];
if(![levelType isKindOfClass:[NSString class]])
{
if(self.generalNewsDetailViewController == nil)
{
GeneralNewsDetailViewController *generalDetail = [[GeneralNewsDetailViewController alloc] initWithNibName:#"GeneralNewsDetailView" bundle:nil];
self.generalNewsDetailViewController = generalDetail;
[generalDetail release];
}
NSDictionary *stream = [self.dataList objectAtIndex:row];
NSString *newsTitle = [stream valueForKey:#"title"];
if( ![newsTitle isKindOfClass:[NSString class]] )
{
generalNewsDetailViewController.newsTitle = #"";
}
else
{
generalNewsDetailViewController.newsTitle =[stream valueForKey:#"title"];
}
generalNewsDetailViewController.newsId = [stream valueForKey:#"id"];
generalNewsDetailViewController.fullText = [stream valueForKey:#"fulltext"];
generalNewsDetailViewController.newsImage = [stream valueForKey:#"images"];
generalNewsDetailViewController.created = [stream valueForKey:#"created"];
HowDo_v1AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
[delegate.generalNewsNavController pushViewController:self.generalNewsDetailViewController animated:YES];
}
else
{
GeneralNewsTableViewController
*generalSubDetail = [[GeneralNewsTableViewController alloc] initWithNibName:#"GeneralNewsTableView" bundle:nil];
NSMutableArray *array;
NSString *titleSelected = (NSString *) [dataList objectAtIndex:row];
if([titleSelected isEqualToString:#"Publishing"])
{
generalSubDetail.title = #"Publishing news detail";
array = [[NSArray alloc] initWithObjects:#"pub News1", #"pub News2",#"pub News3",nil];
generalSubDetail.atLevel = #"level1";
}
else if ([titleSelected isEqualToString:#"Broadcasting"])
{
generalSubDetail.title = #"Broadcasting news detail";
/// START
[self performSelectorOnMainThread:#selector(startIndicator) withObject:nil waitUntilDone:YES];
if(jSONDataAccessWrapper == nil)
{
jSONDataAccessWrapper = [JSON_DataAccess_Wrapper alloc];
}
array = [jSONDataAccessWrapper downloadJSONFeed];
[self performSelectorOnMainThread:#selector(stopIndicator) withObject:nil waitUntilDone:YES];
generalSubDetail.atLevel = #"level2";
}
else if ([titleSelected isEqualToString:#"Marketing Services"])
{
generalSubDetail.title = #"Marketing Services news detail";
array = [[NSArray alloc] initWithObjects:#"Marketing News1", #"Marketing News2",#"Marketing News3",nil];
generalSubDetail.atLevel = #"level1";
}
generalSubDetail.dataList = array;
[self.navigationController pushViewController:generalSubDetail animated:YES];
[titleSelected release];
}
}
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
//- (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSIndexPath *) section
{
return [self.dataList count];
}
Cheers for any feedback
Frames
It is usually recommended by Apple that operations on user interface should be done on the main thread.
What you can do is to defer the callback into the main thread:
- (void)startIndicator
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[self performSelectorOnMainThread:#selector(startAnimating:) withObject:nil waitUntilDone:NO];
[pool release];
}
- (void)startAnimating:(id)sender
{
[(UIActivityIndicatorView *)[self navigationItem].rightBarButtonItem.customView startAnimating];
}
Check out the Thread Guide from Apple. It contains useful information.