0

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]];
    }
Submerged
  • 646
  • 1
  • 10
  • 16

2 Answers2

1

Would you try executing this code of yours:

EAGLView *eagl = [[EAGLView alloc] initWithFrame:[UIScreen mainScreen].bounds];
eagl.animationInterval = 1.0 / 60.0;
[eagl startAnimation];
self.view = eagl;

inside of loadView? I am not sure about why your view is behaving like you say, but that is the place where you are supposed to build your UI... so it might make a difference...

Furthermore, I would call [eagl startAnimation]; only in viewDidLoad...

Hope it helps...

sergio
  • 68,819
  • 11
  • 102
  • 123
1

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.

Craig Otis
  • 31,257
  • 32
  • 136
  • 234
  • The problem is I need a graphViewController for every ticker string, which could be say 20, so once it's defined, it becomes != nil and therefore the same graphViewController is used each time I push it onto the stack. However, I might be able to store these graphViewControllers in a NSMutableDictionary with ticker as the key. Let me give that a try and report back. Thanks a lot! :) – Submerged Dec 01 '11 at 12:31
  • Without the details of your app we can only speculate, but it sounds like you need to redesign things a bit - either adding a setter for the ticker string (if you only show one GraphViewController at a time) or as you mention, keeping a dictionary with the ticker as the key. – Craig Otis Dec 01 '11 at 12:55
  • Thanks for your prompt response craig. I would be willing to resign things -- let me give you a brief understanding of what I want to do. I have a Navigation View Controller that has a RootViewController with a Table. The table contains several stock strings. Let's say RIMM,APPL,GOOG for now. When one is pressed, it loads the GraphViewController with the initWithTicker method and associates a Nibless openGL view (EAGLVIEW) with that controller. Inside that OpenGL view is a drawView method which does the drawing of a graph onto the screen. This loop never stops as you know. – Submerged Dec 01 '11 at 13:07
  • It sounds like you might want to make the ticker string on your GraphViewController 'settable.' That is, right before you push the view controller on screen, you set the ticker string: `vc.tickerString = @"RIMM";` or similar. This way, you only need one view controller. (Which will save you memory, computation time, etc.) – Craig Otis Dec 01 '11 at 13:37
  • Thanks Craig, your suggestion is the one I ended up going with. I will put the solution in my comments. I ultimately decided to use one instance variable of a GraphViewController. I am releasing it each time if != nil and reinitializing it. Is this ideal or will this work just fine? graphView = [[GraphViewController alloc] initWithTicker:[listOfItems objectAtIndex:indexPath.row]]; The reason I am re-initializing it each time, rather than storing the view controller and pushing it onto the stack again is the EAGLView didn't like being popped and pushed onto the stack from portrait to landscape – Submerged Dec 01 '11 at 15:39
  • 1
    Yea, if that works for you, it should be okay. Not sure what's up with the portrait/landscape issue, but I would just recommend profiling your app in Instruments to make sure you're not leaking memory anywhere. – Craig Otis Dec 01 '11 at 16:06