iphoneopengl-esuinavigationcontrollereaglview

UINavigationController and pushing an openGL UIView = never ending loops


I am trying to push an opengl UIView to my navigation controller like this

GraphViewController *gvc = [[GraphViewController alloc] initWithTicker:[listOfItems objectAtIndex:indexPath.row]];
[self.navigationController pushViewController:gvc animated:YES];
[gvc release];

The initWithTicker method looks like this

-(id) initWithTicker:(NSString*)ticker{
self = [super initWithNibName:nil bundle:nil];
if (self) {
    self.title = ticker;
    EAGLView *eagl = [[EAGLView alloc] initWithFrame:[UIScreen mainScreen].bounds];
    eagl.animationInterval = 1.0 / 60.0;
    [eagl startAnimation];
    self.view = eagl;
}
return self;

}

When I go back and forward in my UINavigationController, the drawView method (in EAGLView) keeps looping. Furthermore, if I pushViewController again, the first one does not stop and a new one is created! I've tried making this an instance variable so only one is created and it has the same effect. I would be grateful if anyone has insight as to why this is happening

sergio Suggestion:

-(id) initWithTicker:(NSString*)ticker{
   self = [super initWithNibName:nil bundle:nil];
   if (self) {
      self.title = ticker;
   }
   return self;
}
// Implement loadView to create a view hierarchy programmatically, without using a nib.

- (void)loadView {
    eagl = [[EAGLView alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.view = eagl;
}


// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
    eagl.animationInterval = 1.0 / 60.0;
    [eagl startAnimation];
    [super viewDidLoad];

}

same behaviour.

---This is how I fixed my drawView looping problem--

-(void)viewDidAppear:(BOOL)animated {
    [eagl startAnimation];
    [super viewDidAppear:animated];
}

-(void)viewDidDisappear:(BOOL)animated {
    [eagl stopAnimation];
    [super viewDidDisappear:animated];

}

--Craigs solution --

if(graphView == nil){
        graphView = [[GraphViewController alloc] initWithTicker:[listOfItems objectAtIndex:indexPath.row]];
    }else{
        [graphView release];
        graphView = [[GraphViewController alloc] initWithTicker:[listOfItems objectAtIndex:indexPath.row]];
    }

Solution

  • Are you creating a new GraphViewController every time you want to push one onto your navigation stack? If so, it doesn't really matter how you're handling the creation of your EAGLView instance variable, since you're never going to be interacting with that view controller again anyway.

    For example:

    1. User taps something, a new GraphViewController is pushed on the stack
    2. User goes back, this view controller continues to run
    3. Return to 1. and repeat (thus creating a SECOND GraphViewController, and then a third, and then a fourth... etc.)

    What you should probably be doing is maintaining your GraphViewController as an instance variable, and only creating it once. This will ensure that you're in turn only creating one EAGLView.

    if (_graphViewController == nil) {
        _graphViewController = [[GraphViewController alloc] initWithTicker:[listOfItems objectAtIndex:indexPath.row]];
    }
    [self.navigationController pushViewController:_graphViewController animated:YES];
    

    Then, be sure to release the view controller in your dealloc method if you're going to be maintaining it as an ivar.