0

I'm making app with section tableview.The section header display district through keyArray. To row of table view, it will display all information including of name, address and distance. I can make it by below code.

Now, I'm going to sort ascending distance in tableview. How can I sort it in 'cellForRowAtIndexPath' method?

My second thought is create NSArray at the outside of cellForRowAtIndexPath method. One is to load plist data and calculate distance. And then, sort it through NSSortDescriptor. If I go to this method, I am not sure how to populate it in section tableview correctly?

Can someone give me some idea or suggestion?

In key array, I use below code to create it in ViewDidLoad and put it into section header.

     //location info draw from plist
     NSArray*tempArray=[[NSArray alloc]init];
     tempArray=[dataDictionary allKeys];
     self.keyArray=[tempArray mutableCopy];

In cellForRowAtIndexPath, it calculate distance between target location and user location. And then display all information in table view row.

    NSString*sectionHeader=[keyArray objectAtIndex:indexPath.section];

    NSArray*sectionHeaderArray=[dataDictionary objectForKey:sectionHeader];

    NSDictionary*targetLat=[sectionHeaderArray objectAtIndex:indexPath.row];
    NSDictionary*targetLong=[sectionHeaderArray objectAtIndex:indexPath.row];

    //location info draw from plist
    CLLocation *targetLocation = [[CLLocation alloc] initWithLatitude:[[targetLat objectForKey:@"latitude"] floatValue] longitude:[[targetLong objectForKey:@"longitude"] floatValue]];

    double distance = [self.myLocation distanceFromLocation:targetLocation]/1000;

    UITableViewCell*cell=[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell==nil) {
    cell=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitlereuseIdentifier:CellIdentifier] autorelease];
    }
    UILabel*nameLabel=(UILabel*)[cell viewWithTag:100];
    UILabel*addLabel=(UILabel*)[cell viewWithTag:101];
    UILabel*latLabel1=(UILabel*)[cell viewWithTag:102];
    UILabel*longLabel1=(UILabel*)[cell viewWithTag:103];
    UILabel*disLabel=(UILabel*)[cell viewWithTag:106];

    NSDictionary*name=[sectionHeaderArray objectAtIndex:indexPath.row];

    NSDictionary*address=[sectionHeaderArray objectAtIndex:indexPath.row];

    nameLabel.text=[name objectForKey:@"name"];

    addrLabel.text=[address objectForKey:@"address"];

    latLabel1.text=[NSString stringWithFormat:@"%f",self.myLocation.coordinate.latitude];
    longLabel1.text=[NSString stringWithFormat:@"%f",self.myLocation.coordinate.longitude];

    disLabel.text=[NSString stringWithFormat:@"%0.2f km",distance];

    return cell;
    }
4

1 回答 1

0

I jumped to conclusions and posted an answer that was flawed. I see now that you have a multitude of issues in your process.

You assign the same object, [sectionHeaderArray objectAtIndex:indexPath.row], to several different variables and are expecting different results from each. To start with, I would make the following changes to your existing code:

   NSString*sectionHeader=[keyArray objectAtIndex:indexPath.section];

   NSArray *locationsForSection = [self.dataDictionary objectForKey:sectionHeader];

   NSDictionary *thisLocationInfo = [locationsForSection objectAtIndex:indexPath.row];
   float thisLat = [[thisLocationInfo objectForKey:@"latitude"] floatValue];
   float thisLong = [[thisLocationInfo objectForKey:@"longitude"] floatValue];

   //location info draw from plist
   CLLocation *targetLocation = [[CLLocation alloc] initWithLatitude:thisLat longitude:thisLong];

   double distance = [self.myLocation distanceFromLocation:targetLocation]/1000;

   UITableViewCell*cell=[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
   if (cell==nil) {
      cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitlereuseIdentifier:CellIdentifier];
   }
   UILabel*nameLabel=(UILabel*)[cell viewWithTag:100];
   UILabel*addLabel=(UILabel*)[cell viewWithTag:101];
   UILabel*latLabel1=(UILabel*)[cell viewWithTag:102];
   UILabel*longLabel1=(UILabel*)[cell viewWithTag:103];
   UILabel*disLabel=(UILabel*)[cell viewWithTag:106];

   NSDictionary*name=[sectionHeaderArray objectAtIndex:indexPath.row];

   NSDictionary*address=[sectionHeaderArray objectAtIndex:indexPath.row];

   latLabel1.text=[NSString stringWithFormat:@"%f",thisLat];
   longLabel1.text=[NSString stringWithFormat:@"%f",thisLong];

   disLabel.text=[NSString stringWithFormat:@"%0.2f km",distance];

   return cell;
}

For your sorting issue, I would say to go back to your dataDictionary. Iterate through each of the sectionHeader arrays. Replace each array with a copy that is sorted by the distance from myLocation. You could add the key, distance, to each dictionary there and take that out of the cellForRowAtIndexPath method entirely.

-(NSDictionary *)dataDictionary
{
   if (_dataDictionary) {
      return _dataDictionary;
   }

   NSMutableDictionary *resultDictionary = [[NSMutableDictionary alloc] init];
   for (NSString *sectionHead in self.keyArray) {
      NSMutableArray *sectionArrayWithDistances = [[NSMutableArray alloc] init];
      NSArray *thisSectionArray = [sourceDictionary objectForKey:sectionHead];
      for (NSDictionary *theLocationDict in thisSectionArray) {
         // Calculate the distance
         float thisLat = [[theLocationDict objectForKey:@"latitude"] floatValue];
         float thisLong = [[theLocationDict objectForKey:@"longitude"] floatValue];
         CLLocation *targetLocation = [[CLLocation alloc] initWithLatitude:thisLat longitude:thisLong];
         double distance = [self.myLocation distanceFromLocation:targetLocation]/1000;

         // Insert modified dictionary into the resulting section array
         NSMutableDictionary *thisLocationWithDistance = [NSMutableDictionary dictionaryWithDictionary:theLocationDict];
         [thisLocationWithDistance insertObject:[NSNumber numberWithDouble:distance] ForKey:@"distance"];
         [sectionArrayWithDistances addObject:[NSDictionary dictionaryWithDictionary:thisLocationWithDistance]];
      }
      // Sort the resulting array for this section and insert in dataDict
      NSSortDescriptor *sortByDistance = [[NSSortDescriptor alloc] initWithKey:@"distance" ascending:YES];
      NSArray *sortDescriptors = [NSArray arrayWithObjects:sortByDistance, nil];
      [sectionArrayWithDistances sortWithDescriptors:sortDescriptors];

      [resultDictionary insertObject:[NSArray arrayWithArray:sectionArrayWithDistances] forKey:sectionHead];
   }

   // Set result and return
   self.dataDictionary = [NSDictionary dictionaryWithDictionary:resultDictionary];
   return _dataDictionary;
}

Total Air Code and turned out to be more than I bargained for. Possible errors in syntax and what not but this is the basic idea as I see it for your purposes.

于 2013-04-21T20:47:50.800 回答