我正在研究estimote beacon。
我尝试在切换Case“立即”时呈现ViewController。 但是当我加载视图时,我有一个警告:
2014-03-13 02:44:26.017 ProximityDemo [856:60b]警告:尝试在窗口层次结构中显示其视图!
为什么?我认为当我在使用新视图时,presentView方法仍在工作。
此外,当我在新视图中时,我希望在我处于Case“Near”时弹出旧视图
我想我必须在新的ViewController中实现所有代码? (presentProductViewController) 有没有办法让所有接近/距离控制只在一个控制器中?
这是我的代码:
ESTViewController:
#import "ESTViewController.h"
#import <ESTBeaconManager.h>
#import "PresentProductViewController.h"
@interface ESTViewController () <ESTBeaconManagerDelegate>
@property (nonatomic, strong) ESTBeaconManager* beaconManager;
@property (nonatomic, strong) ESTBeacon* selectedBeacon;
@end
@implementation ESTViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
/////////////////////////////////////////////////////////////
// setup Estimote beacon manager
// craete manager instance
self.beaconManager = [[ESTBeaconManager alloc] init];
self.beaconManager.delegate = self;
self.beaconManager.avoidUnknownStateBeacons = YES;
// create sample region object (you can additionaly pass major / minor values)
ESTBeaconRegion* region = [[ESTBeaconRegion alloc] initWithProximityUUID:ESTIMOTE_IOSBEACON_PROXIMITY_UUID
identifier:@"EstimoteSampleRegion"];
// start looking for estimote beacons in region
// when beacon ranged beaconManager:didRangeBeacons:inRegion: invoked
[self.beaconManager startRangingBeaconsInRegion:region];
}
-(void)beaconManager:(ESTBeaconManager *)manager
didRangeBeacons:(NSArray *)beacons
inRegion:(ESTBeaconRegion *)region
{
if([beacons count] > 0)
{
if(!self.selectedBeacon)
{
// initialy pick closest beacon
self.selectedBeacon = [beacons objectAtIndex:0];
}
else
{
for (ESTBeacon* cBeacon in beacons)
{
// update beacon it same as selected initially
if([self.selectedBeacon.major unsignedShortValue] == [cBeacon.major unsignedShortValue] &&
[self.selectedBeacon.minor unsignedShortValue] == [cBeacon.minor unsignedShortValue])
{
self.selectedBeacon = cBeacon;
}
}
}
// beacon array is sorted based on distance
// closest beacon is the first one
NSString* labelText = [NSString stringWithFormat:
@"Major: %i, Minor: %i\nRegion: ",
[self.selectedBeacon.major unsignedShortValue],
[self.selectedBeacon.minor unsignedShortValue]];
// calculate and set new y position
switch (self.selectedBeacon.proximity)
{
case CLProximityUnknown:
{
labelText = [labelText stringByAppendingString: @"Unknown"];
break;
}
case CLProximityImmediate:
{
labelText = [labelText stringByAppendingString: @"Immediate"];
PresentProductViewController *showViewController = [[PresentProductViewController alloc] initWithNibName:@"PresentProductViewController" bundle:nil];
[self presentViewController:showViewController animated:YES completion:nil];
break;
}
case CLProximityNear:
{
labelText = [labelText stringByAppendingString: @"Near"];
break;
//[self.navigationController popToRootViewControllerAnimated:YES];
//ESTViewController *initViewController = [[ESTViewController alloc]init];
//[self presentViewController:initViewController animated:YES completion:nil];
}
case CLProximityFar:
{
labelText = [labelText stringByAppendingString: @"Far"];
break;
}
default:
break;
}
self.distanceLabel.text = labelText;
}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
PresentProductViewController:
#import "PresentProductViewController.h"
#import <ESTBeaconManager.h>
#import "ESTViewController.h"
@interface PresentProductViewController () <ESTBeaconManagerDelegate>
@property (nonatomic, strong) ESTBeaconManager* beaconManager;
@property (nonatomic, strong) ESTBeacon* selectedBeacon;
@end
@implementation PresentProductViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[self.activityIndicator startAnimating];
/////////////////////////////////////////////////////////////
// setup Estimote beacon manager
// craete manager instance
self.beaconManager = [[ESTBeaconManager alloc] init];
self.beaconManager.delegate = self;
self.beaconManager.avoidUnknownStateBeacons = YES;
// create sample region object (you can additionaly pass major / minor values)
ESTBeaconRegion* region = [[ESTBeaconRegion alloc] initWithProximityUUID:ESTIMOTE_IOSBEACON_PROXIMITY_UUID
identifier:@"EstimoteSampleRegion"];
// start looking for estimote beacons in region
// when beacon ranged beaconManager:didRangeBeacons:inRegion: invoked
[self.beaconManager startRangingBeaconsInRegion:region];
}
-(void)beaconManager:(ESTBeaconManager *)manager
didRangeBeacons:(NSArray *)beacons
inRegion:(ESTBeaconRegion *)region
{
if([beacons count] > 0)
{
if(!self.selectedBeacon)
{
// initialy pick closest beacon
self.selectedBeacon = [beacons objectAtIndex:0];
}
else
{
for (ESTBeacon* cBeacon in beacons)
{
// update beacon it same as selected initially
if([self.selectedBeacon.major unsignedShortValue] == [cBeacon.major unsignedShortValue] &&
[self.selectedBeacon.minor unsignedShortValue] == [cBeacon.minor unsignedShortValue])
{
self.selectedBeacon = cBeacon;
}
}
}
// beacon array is sorted based on distance
// closest beacon is the first one
self.labelText.text = [NSString stringWithFormat:
@"Major: %i, Minor: %i\nRegion: ",
[self.selectedBeacon.major unsignedShortValue],
[self.selectedBeacon.minor unsignedShortValue]];
// calculate and set new y position
switch (self.selectedBeacon.proximity)
{
case CLProximityUnknown:
{
self.labelText.text = [self.labelText.text stringByAppendingString: @"Unknown"];
break;
}
case CLProximityImmediate:
{
self.labelText.text = [self.labelText.text stringByAppendingString: @"Immediate"];
break;
}
case CLProximityNear:
{
self.labelText.text = [self.labelText.text stringByAppendingString: @"Near"];
break;
//UIStoryboard *storyBoard = [UIStoryboard storyboardWithName:@"Main.storyboard" bundle:nil];
//UIViewController *initViewController = [storyBoard instantiateInitialViewController];
//[self.navigationController pushViewController:initViewController animated:YES];
//ESTViewController *initViewController = [[ESTViewController alloc]init];
//[self presentViewController:initViewController animated:YES completion:nil];
//[self.navigationController popToRootViewControllerAnimated:YES];
}
case CLProximityFar:
{
self.labelText.text = [self.labelText.text stringByAppendingString: @"Far"];
break;
}
default:
break;
}
}
}
-(void)viewDidDisappear:(BOOL)animated
{
[self.activityIndicator stopAnimating];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
我确定我做错了。
谢谢你的帮助。
答案 0 :(得分:1)
即使您提交ESTBeaconManager
,didRangeBeacons:inRegion
也可能会通过PresentProductViewController
不断提供最新更改。我认为以下是会发生的事情:
ESTViewController
使用非空信号数组调用didRangeBeacons:inRegion
。proximity
属性为CLProximityImmediate
,PresentProductViewController
以模态显示。ESTViewController
&#39; s didRangeBeacons:inRegion
。同样,信标具有即时接近性,并且PresentProductViewController
的新实例以模态呈现。来自ViewController Programming Guide
任何视图控制器对象都可以一次呈现单个视图控制器。
如果上面列出的假设是正确的,那么您试图同时以模态方式呈现多个视图控制器,这不是有效的操作。当视图消失时,您可以尝试停止信标的测距,然后在显示时再次开始测距。这将阻止信标管理器在无法呈现视图控制器的情况下通知ESTViewController
更改。覆盖viewWillDisappear
和viewWillAppear
方法来实现此目的:
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self.beaconManager stopRangingBeaconsInRegion:region];
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self.beaconManager startRangingBeaconsInRegion:region];
}