2012-04-09 20 views
8

Ho un GLKViewController per gestire un disegno OpenGL. Ho il metodo glkView:drawInRect e update entrambi implementati e la proprietà preferredFramesPerSecond è impostata su 30 (impostazione predefinita).GLKViewControllerDelegate getting blocked

Il problema è che i metodi delegati interrompono l'attivazione quando l'utente interagisce con altre parti dell'app. I due casi in cui ho visto accadere sono quando l'utente scorre un UITableView o interagisce con un MKMapView.

C'è un modo per assicurarsi che questi delegati si attivino sempre, indipendentemente da ciò che sta facendo il resto dell'app. L'unica volta che voglio che questi si fermino è quando l'app entra in background (cosa che avviene automaticamente).

+0

Potresti postare del codice? – prince

+0

Non c'è alcun codice di reablen. Con l'init di 'GLKViewController' ho impostato' preferredFramesPerSecond' su 30. –

risposta

15

La ragione di ciò è che durante lo scorrimento in una vista tabella o in una vista mappa il runloop è in UITrackingRunLoopMode che ha una priorità più alta rispetto alla modalità predefinita. Ciò impedisce l'attivazione di alcuni eventi al fine di garantire prestazioni di scorrimento elevate.

Per risolvere il problema, è necessario impostare il proprio ciclo di rendering anziché affidarsi allo GLKViewController.

  • primo set enableSetNeedsDisplay del GLKView a NO (dovrebbe essere impostata automaticamente quando si usano GLKViewController).
  • impostato preferredFramesPerSecond-0 (o forse 1) per disabilitare il loop rendering di GLKViewController o non utilizzare affatto GLKViewController
  • Importare il quadro QuartzCore: #import <QuartzCore/QuartzCore.h>
  • creare un CADisplayLink e pianificare in NSRunLoopCommonModes:
 
CADisplayLink* displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(render:)]; 
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; 
  • opzionale: impostare la frameInterval di DisplayLink a 2 (= metà framerate)
  • il metodo Render:
 
- (void)render:(CADisplayLink*)displayLink { 
    GLKView* view = (GLKView*)self.view; 
    [view display]; 
} 

non ho ancora testato questo, così dimmi se funziona!

+3

Questo funziona. Stavo cercando un modo in cui non dovevo farlo, ma penso che tu abbia ragione che questa è l'unica strada da percorrere. –

+0

Per qualche motivo, questo fa sì che il framerate scenda a 2 secondi per frame! –

+0

@JosephHumfrey controlla la proprietà frameInterval di CADisplayLink (valore predefinito = 1). Forse l'hai impostato a 30 per errore? Il framerate dovrebbe essere uguale a '1/(displayLink.frameInterval * displayLink.duration)' – Felix

Problemi correlati