views:

157

answers:

1

hi,

i have the corelocation stuff in an uitableview controller. i actually want to get a distance from two locations and print that distance in a tableview cell.

the problem is, that the tableview is filled before all the corelocation stuff happens. how can i make corelocation makes all updates before the table is filled?

heres my class:

//
//  EntriesListViewController.m
//  OEAW_App
//
//  Created by Clemens on 6/6/10.
//  Copyright 2010 __MyCompanyName__. All rights reserved.
//

#import "EntriesListViewController.h"
#import "EntryDetailController.h"


@implementation EntriesListViewController

@synthesize locationManager;
@synthesize delegate;

NSMutableDictionary *entries;
NSMutableDictionary *dictionary;

CLLocation *coords;

/*- (id) init {
    self = [super init];
    if (self != nil) {
        self.locationManager = [[[CLLocationManager alloc] init] autorelease];
        self.locationManager.delegate = self;
    }
    return self;
}*/

- (CLLocationManager *)locationManager {

    if (locationManager != nil) {
        return locationManager;
    }

    locationManager = [[CLLocationManager alloc] init];
    locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
    locationManager.delegate = self;

    return locationManager;
}

- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation
{
    //coords.longitude = newLocation.coordinate.longitude;
    //coords.latitude = newLocation.coordinate.latitude;
    coords = newLocation;
    NSLog(@"Location: %@", [newLocation description]);
}

- (void)locationManager:(CLLocationManager *)manager
             didFailWithError:(NSError *)error
{
    NSLog(@"Error: %@", [error description]);
}


- (void)viewDidLoad {

    //[[MyCLController alloc] init];
    //[locationManager startUpdatingLocation];

    [[self locationManager] startUpdatingLocation];

    //---initialize the array--- 
    //entries = [[NSMutableArray alloc] init];

    //---add items--- 
    //NSString *Path = [[NSBundle mainBundle] bundlePath];
    //NSString *DataPath = [Path stringByAppendingPathComponent:@"Memorials.plist"];

    dictionary = [[NSDictionary alloc] initWithContentsOfURL:[NSURL URLWithString: @"http://akm.madison.at/memorials.xml"]];

    /*NSDictionary *dssItem = [dictionary objectForKey:@"1"];
    NSString *text = [dssItem objectForKey:@"text"];
    */

    //entries = [[NSMutableDictionary alloc] init];

    NSLog(@"%@", dictionary);


    //Path get the path to MyTestList.plist
    NSString *path=[[NSBundle mainBundle] pathForResource:@"Memorials" ofType:@"plist"];
    //Next create the dictionary from the contents of the file.
    NSDictionary *dict=[NSDictionary dictionaryWithContentsOfFile:path];

    //now we can use the items in the file.
//  self.name.text = [dict valueForKey:@"Name"] ;
    NSLog(@"%@",[dict valueForKey:@"Name"]);

    //---set the title--- 
    self.navigationItem.title = @"Türkendenkmäler";

    [super viewDidLoad];   
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    // Return the number of rows in the section.
    return [dictionary count];
}

// Customize the appearance of table view cells.
- (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];
    }

    // Configure the cell...
    NSArray *keys = [dictionary allKeys];
    id key = [keys objectAtIndex:indexPath.row];
    NSDictionary *tmp = [dictionary objectForKey:key];
    NSString *name = [tmp objectForKey:@"name"];
    cell.textLabel.text = name;
    cell.font = [UIFont fontWithName:@"Helvetica" size:12.0];

    CLLocation *location = [[CLLocation alloc] initWithLatitude:[[tmp valueForKey:@"coords_x"] floatValue] 
                                                                                                        longitude:[[tmp valueForKey:@"coords_y"] floatValue]];

    /*CLLocation *newLoc = [[CLLocation alloc] initWithLatitude:coords.latitude 
                                                                                                        longitude:coords.longitude];*/


    //locationController = [[MyCLController alloc] init];



    int distance = [coords distanceFromLocation:location];

    NSLog(@"%@",distance);
    cell.detailTextLabel.text = [NSString stringWithFormat:@"%@m",distance];
    //NSLog(@"%@", [getLocation newLoc]);

    return cell;
}

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

    EntryDetailController *detailViewController = 
    [[EntryDetailController alloc]
     initWithNibName:@"EntryDetailController" bundle:nil];

    //detailViewController.entrySelected = [dictionary objectAtIndex:indexPath.row];

    NSArray *keys = [dictionary allKeys];
    id key = [keys objectAtIndex:indexPath.row];
    NSDictionary *tmp = [dictionary objectForKey:key];
    NSString *name = [tmp objectForKey:@"name"];
    detailViewController.entrySelected_name = name;

    NSString *location = [tmp objectForKey:@"location"];
    detailViewController.entrySelected_location = location;

    NSString *type = [tmp objectForKey:@"type"];
    detailViewController.entrySelected_type = type;

    NSString *slug = [tmp objectForKey:@"slug"];
    detailViewController.entrySelected_slug = slug;


    [self.navigationController pushViewController:detailViewController animated:YES];
    [detailViewController release];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}

- (void)dealloc {
    [entries release];
    [super dealloc];
}


@end
A: 

Preventing the table view from updating until after the location manager does may be possible, but there is an easier way that is probably more meaningful for your users. I would accomplish this using a two-step process.

  1. In the cellForRowAtIndexPath method, provide some meaningful value for distance that indicates to users that the location has not updated yet. For example, check if your coords value is nil, and if so, set cell.detailTextLabel.text to "?" or "-" or the like.
  2. In locationManager:didUpdateToLocation:fromLocation, put this line of code

[self.tableView reloadData];

This way the distance value in your table view cell will continue to update as the location manager gets more precise data. This also has the added benefit of presenting meaningful data even if the location manager never gets updated, as opposed to your method which would never show your table view.

Drew C