I have the following code that ranges iBeacons and refreshes a table view with them.
A user can tap on a beacon in that table to select it. However, I'm seeing that with a 4 of beacons nearby, the table updates too frequently, about once a second. By the time I can tap on a row, another row might appear in it's place.
Has anyone solved the problem of how to "stabilize" the table view that displays iBeacons? in other words, if a user wants to select a row, I want to make sure that this row does not suddenly get a different beacon loaded into it.
My code that refreshes the tableview
-(void)beaconManager:(ESTBeaconManager *)manager
didRangeBeacons:(NSArray *)beacons
inRegion:(ESTBeaconRegion *)region
{
++updateCounter;
NSMutableDictionary* datasource = [NSMutableDictionary dictionary];
NSMutableArray* near = [NSMutableArray array];
NSMutableArray* far = [NSMutableArray array];
for(ESTBeacon* beacon in beacons)
{
NSString* name = [NSString stringWithFormat:@"Beacon (%i,%i), update:%i",beacon.major.intValue,beacon.minor.intValue,updateCounter];
if(beacon.proximity == CLProximityFar||
beacon.proximity == CLProximityUnknown)
{
[far addObject:name];
}else if(beacon.proximity == CLProximityNear||
beacon.proximity == CLProximityImmediate)
{
[near addObject:name];
}
}
[datasource setObject:near forKey:@"near"];
[datasource setObject:far forKey:@"far"];
[self.beaconDelegate setDatasource:datasource];
}
//within the tableview
-(void)setDatasource:(NSDictionary *)datasource
{
_datasource = datasource;
[self.tableView reloadData];
}
I do this in the Locate app by sorting the rows by the UUID/major/minor. In an early revision, I tried sorting by distance, but I found that was too variable. Using the identifiers as the sort order proved to be an acceptably stable solution.
PS. if beacons jump and appear/disappear, check if their refresh interval is set to be greater than 1 second.
NSArray* nearSorted = [near sortedArrayUsingComparator:^NSComparisonResult(ESTBeacon* a, ESTBeacon* b) {
NSString* key1 = [NSString stringWithFormat:@"%@%i%i",[a.proximityUUID UUIDString],a.major.intValue,a.minor.intValue];
NSString* key2 = [NSString stringWithFormat:@"%@%i%i",[b.proximityUUID UUIDString],b.major.intValue,b.minor.intValue];
return [key1 compare:key2];
}];
NSArray* farSorted = [far sortedArrayUsingComparator:^NSComparisonResult(ESTBeacon* a, ESTBeacon* b) {
NSString* key1 = [NSString stringWithFormat:@"%@%i%i",[a.proximityUUID UUIDString],a.major.intValue,a.minor.intValue];
NSString* key2 = [NSString stringWithFormat:@"%@%i%i",[b.proximityUUID UUIDString],b.major.intValue,b.minor.intValue];
return [key1 compare:key2];
}];