Демонстрация близости маяков Estimote, запускающая ViewController в Immediate Case

Я работаю над оценочным маяком.

Я пытаюсь представить ViewController, когда я нахожусь в случае переключения «немедленно». Но когда я загружаю представление, у меня есть предупреждение:

2014-03-13 02:44:26.017 ProximityDemo[856:60b] Предупреждение: Попытка представить, чье представление не находится в иерархии окон!

Почему ? Я думаю, что метод PresentView все еще работает, пока я нахожусь в новом представлении.

Также, когда я нахожусь в новом представлении, я хотел бы перейти к старому представлению, когда я нахожусь в случае «Рядом»

Думаю, мне нужно реализовать весь код в новом 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

Презентупродуктвиевконтроллер :

#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

Я уверен, что делаю неправильно. Спасибо за вашу помощь.


person mad_mask    schedule 13.03.2014    source источник


Ответы (1)


ESTBeaconManager, вероятно, постоянно доставляет последние изменения через didRangeBeacons:inRegion, даже если вы представили PresentProductViewController. Я думаю, что происходит следующее:

  1. didRangeBeacons:inRegion ESTViewController вызывается с непустым массивом маяков.
  2. Свойство proximity выбранных маяков равно CLProximityImmediate, а PresentProductViewController представлено модально.
  3. Будучи представленным (не представленным) контроллером представления, didRangeBeacons:inRegion ESTViewController вызывается с новыми изменениями. Опять же, маяк имеет непосредственную близость, и новый экземпляр PresentProductViewController представлен модально.

Из Руководства по программированию ViewController

Любой объект контроллера представления может одновременно представлять один контроллер представления.

Если предположение, изложенное выше, верно, вы пытаетесь модально представить несколько контроллеров представления одновременно, что не является допустимым действием. Вы можете попытаться остановить ранжирование маяков, когда представление исчезнет, ​​а затем начать ранжирование снова, когда оно появится. Это не позволит диспетчеру маяка уведомлять 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];
}
person Kasper Munck    schedule 13.03.2014
comment
Большое спасибо, Мунккен. Это сработало для предупреждающего сообщения. Не могли бы вы помочь мне с поп-бэком, пожалуйста? Когда я нахожусь в непосредственном случае, я представляю новое представление, не получая предупреждающего сообщения. Теперь я хочу, чтобы вид возвращался, когда я ухожу от маяка. - person mad_mask; 14.03.2014
comment
Все в порядке, я нашел это. Я использовал Раскадровку. и я просто добавил [self.navigationController popToRootViewControllerAnimated:YES]; в случае swith рядом с presentViewController. Спасибо еще раз - person mad_mask; 14.03.2014
comment
Рад слышать, что вы разобрались. - person Kasper Munck; 14.03.2014