The proximity and accuracy values appear to be quite 'noisy'. It can also depend on your environment. Water (and therefore people) absorbs the frequencies used by Bluetooth so people moving can have an impact, but I observe variation in between 1.2m and 1.9m when both devices are sitting on my desk.
I think you are going to have to deal with the noise in your app. Once a view has opened you should keep it open until the beacon is 'far' (or you get a region exit) for some period of time. If the state transitions back to near or immediate then reset the timer.
You need to use some code similar to the following -
-(void)locationManager:(CLLocationManager *)manager
didRangeBeacons:(NSArray *)beacons
inRegion:(CLBeaconRegion *)region {
CLBeacon *beacon=beacons[0];
switch (beacon.proximity) {
case CLProximityFar:
if (self.farTimer==nil) {
self.farTimer=[NSTimer scheduledTimerWithTimeInterval:30 target:self selector:@selector(farTimerFired:) userInfo:beacon repeats:NO];
}
break;
case CLProximityNear:
case CLProximityImmediate:
if (self.farTimer!=nil) {
[self.farTimer invalidate];
self.farTimer=nil;
}
break;
case CLProximityUnknown:
NSLog(@"Beacon proximity is unknown");
break;
}
}
-(void) farTimerFired:(NSTimer *)timer {
CLBeacon *beacon=(CLBeacon *)timer.userInfo;
NSLog(@"Beacon %@ is really far",beacon.proximityUUID.UUIDString);
self.farTimer=nil;
}