
Question:
Hai I am new to xcode i use a UITableView to display the vehicle number and its location. it use network for find the location. My problem is every time i scroll the table that time only it reloads the location from the net. Is it possible to load the datas for the first time and bind the table only once. Then I can scroll smoothly.Kindly advice me my code is bellow...
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:@"MainCell"];
if(cell==nil)
{
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MainCell"];
cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
}
NSString *Vehicleno=[Vehicle_No objectAtIndex:indexPath.row];
NSString *urlMapString=[NSString stringWithFormat:@"http://logix.com/logix_webservice/map.php?format=json&truckno=%@",Vehicleno];
NSURL *urlMap=[NSURL URLWithString:urlMapString];
NSData *dataMap=[NSData dataWithContentsOfURL:urlMap];
NSError *errorMap;
NSDictionary *jsonMap = [NSJSONSerialization JSONObjectWithData:dataMap options:kNilOptions error:&errorMap];
NSArray *resultsMap = [jsonMap valueForKey:@"posts"];
NSArray *resMap = [resultsMap valueForKey:@"post"];
NSArray *latitudeString=[resMap valueForKey:@"latitude"];
if([latitudeString count]>0){
NSString *latOrgstring = [latitudeString objectAtIndex:0];
double latitude=[latOrgstring doubleValue];
NSArray *longitudeString=[resMap valueForKey:@"longitude"];
NSString *longOrgstring = [longitudeString objectAtIndex:0];
double longitude=[longOrgstring doubleValue];
//MAP VIEW Point
MKCoordinateRegion myRegion;
//Center
CLLocationCoordinate2D center;
center.latitude=latitude;
center.longitude=longitude;
//Span
MKCoordinateSpan span;
span.latitudeDelta=THE_SPAN;
span.longitudeDelta=THE_SPAN;
myRegion.center=center;
myRegion.span=span;
//Set our mapView
[MapViewC setRegion:myRegion animated:NO];
CLLocation *someLocation=[[CLLocation alloc]initWithLatitude:latitude longitude:longitude];
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:someLocation completionHandler:^(NSArray *placemarks, NSError *error) {
if ([placemarks count] > 0) {
NSDictionary *dictionary = [[placemarks objectAtIndex:0] addressDictionary];
addressOutlet=[dictionary valueForKey:@"Street"];
City=[dictionary valueForKey:@"City"];
State=[dictionary valueForKey:@"State"];
if (addressOutlet!=NULL&&City!=NULL)
{
NSString *SubTitle=[NSString stringWithFormat:@"%@,%@,%@",addressOutlet,City,State];
cell.detailTextLabel.text=SubTitle;
}
else if (addressOutlet==NULL&&City!=NULL)
{
NSString *SubTitle=[NSString stringWithFormat:@"%@,%@",City,State];
cell.detailTextLabel.text=SubTitle;
}
else if (addressOutlet!=NULL&&City==NULL)
{
NSString *SubTitle=[NSString stringWithFormat:@"%@,%@",addressOutlet,State];
cell.detailTextLabel.text=SubTitle;
}
else if(addressOutlet==NULL&&City==NULL&&State!=NULL)
{
NSString *SubTitle=[NSString stringWithFormat:@"%@",State];
cell.detailTextLabel.text=SubTitle;
}
else if (addressOutlet==NULL&&City==NULL&&State==NULL)
{
NSString *SubTitle=[NSString stringWithFormat:@"%@",@""];
cell.detailTextLabel.text=SubTitle;
}
}
}];
}
NSUInteger row = [indexPath row];
cell.textLabel.text=[Vehicle_No objectAtIndex:row];
cell.backgroundColor=[UIColor clearColor];
return cell;
}
Thanks in advance..
Answer1:The main thread is used for interface operations. If you post a network request there it gets blocked, because it is waiting for the network. Post it in a background thread. Do some research on how to work with Grand Central Dispatch, blocks and Concurrency Programming. Those parts will help you out.
Answer2:The good practice is to fetch your data outside from your "feeding" method. You can proceed like this:
At the top of your ViewController
:
@implementation MyCustomViewController {
NSMutableArray *storeArray;
UITableView *myTableView;
}
In your view viewDidLoad
init your array, init your UITableView
and run a method which is filling it:
- (void)viewDidLoad
{
/ Init your NSMutableArray
storeArray = [[NSMutableArray alloc] init];
[super viewDidLoad];
// Do any additional setup after loading the view.
// Init your tableView
myTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
myTableView.delegate = self;
myTableView.datasource = self;
[self addSubview:myTableView];
// Run your method
[self downloadMyData];
}
Implement your code for downloading your data:
- (void)downloadMyData
{
// All your code here in order to download your data
// And store them in your array
[storeArray addObject:object];
// When you have all your data downloaded, you have to reload your tableview:
[myTableView reloadData];
}
Finally, implement your UITableView protocol
and fill your cell with the data in your storeArray
:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell=[tableView dequeueReusableCellWithIdentifier:@"MainCell"];
if(cell==nil)
{
cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MainCell"];
cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
// Access your data via your array
data1 = [storeArray objectAtIndex:indexPath.row];
cell.dataX = data1
// ETC....
}
}
Basically, some data are fetched from the web every time a cell is displayed, that's why your view appear to be very slow.