2010-07-21 7 views
20

La mia applicazione è composta da una barra degli strumenti e da un AVCaptureVideoPreviewLayer in un UIView in background. Mi piacerebbe vedere che ruotano barra degli strumenti per quanto riguarda l'orientamento del dispositivo, in modo a mio principale ViewController, ho implementato la funzione:Disabilitazione della rotazione automatica per un UIView

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 
{ 
    return (interfaceOrientation == UIInterfaceOrientationPortrait 
      || interfaceOrientation == UIInterfaceOrientationLandscapeLeft 
      || interfaceOrientation == UIInterfaceOrientationLandscapeRight); 
} 

Questo funziona bene, ma quando l'orientamento interfaccia è cambiato, vedo che lo sfondo Anche UIView (con un livello video) sta ruotando, quindi la mia vista video ora sta giocando a 90 gradi a sinistra oa destra ... Il che non è proprio bello!
Quindi la mia domanda è: c'è un modo per disabilitare l'animazione di rotazione automatica su un UIView specifico?

ho visto una domanda simile a questo: Disabling autorotate for a single UIView, ma le risposte non va bene il mio problema, ho davvero bisogno background vista a non muoversi, non per aggirare il problema con una sorta di "animazione contatore ". Così ho deciso di portare questo argomento.

Qualche idea?

Grazie!

+0

Ho lo stesso problema. L'hai risolto? funziona con iOS 6? Potresti inserire una risposta completa? Molte grazie. –

risposta

-2

Prova questo:

myVideoCaptureLayer.orientationSupported = NO; 
+5

Come ho capito, la proprietà orientationSupport è in sola lettura e indica se il dispositivo è in grado di cambiare l'orientamento del video. Se è vero, allora si può cambiare la proprietà "orientamento" al valore corretto (AVCaptureVideoOrientationPortrait, AVCaptureVideoOrientationLandscapeLeft, ...). Grazie per avermi messo nella buona direzione! –

+0

Whoops! Manca la parte di sola lettura. Sono contento che ci abbia aiutato. – christo16

2
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 
    return NO; 
} 

O stavi dicendo di disabilitarlo solo quando viene visualizzata una determinata vista? In tal caso, puoi verificarlo utilizzando il metodo isDescendantOfView di UIView.

+1

Bene, non voglio disabilitare l'intera rotazione dell'interfaccia, solo per disabilitarla su un UIView specifico nella gerarchia della vista del viewController principale. Significa che quando ruoto il dispositivo, vedo la barra degli strumenti rotante, ma non la vista del video. –

+0

Questo non è un metodo su UIView - è su UIViewController. Quindi disabiliterebbe la rotazione per l'intera gerarchia della vista. – colinta

+0

Questo è quello che stavo cercando ... – ATOzTOA

1

Ho incontrato lo stesso problema, anche se semplicemente impostando la proprietà di orientamento sul AVCaptureVideoPreviewLayer non era sufficiente. Il problema aggiuntivo è che CALayer non supporta i gestori di layout su iPhone, quindi la cornice del livello video potrebbe non essere corretta quando il dispositivo viene ruotato.

Ho risolto questo problema utilizzando un UIView personalizzato per contenere AVCaptureVideoPreviewLayer e quindi ho annullato il metodo layoutSubviews per questa vista per garantire che la cornice del livello video sia sempre impostata correttamente. Questo è anche un buon posto per impostare la proprietà di orientamento. Cioè, il mio UIView assomiglia:

@implementation VideoPreview 

@synthesize previewLayer; 

- (void) layoutSubviews { 
    if (previewLayer) { 
     // set the correct orientation for the video layer 
     previewLayer.orientation = [[UIDevice currentDevice] orientation]; 

     // and set its frame to that of its parent UIView 
     previewLayer.frame = self.bounds; 
    } 
} 

- (void) addPreviewLayer: (AVCaptureVideoPreviewLayer *) videoLayer { 
    previewLayer = videoLayer; 
    [self.layer addSublayer:videoLayer]; 
} 

@end 
11

Questo post indicato nella direzione giusta. Per ottenere un AVCaptureVideoPreviewLayer a non ruotare con il dispositivo ho avvolto in un UIView e animato che guarda nella direzione opposta:

- (void) willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { 

    float rotation; 

    if (toInterfaceOrientation==UIInterfaceOrientationPortrait) { 
     rotation = 0; 
    } else 
    if (toInterfaceOrientation==UIInterfaceOrientationLandscapeLeft) { 
     rotation = M_PI/2; 
    } else 
    if (toInterfaceOrientation==UIInterfaceOrientationLandscapeRight) { 
     rotation = -M_PI/2; 
    } 

    [UIView animateWithDuration:duration animations:^{ 
     cameraPreview.transform = CGAffineTransformMakeRotation(rotation); 
     cameraPreview.frame = self.view.frame; 
    }]; 
} 

Sembra un po 'rotonda ma un'animazione fluida. Altre viste sopra il livello di anteprima ruotano automaticamente come dovrebbero.

+0

Grazie! Che ha fatto per me. – KPM

+0

Ho modificato leggermente il codice: CGRect f = cameraPreview.frame; cameraPreview.transform = CGAffineTransformMakeRotation (rotazione); cameraPreview.frame = f; – colinta

+0

Salve, Grazie per questo, 'self.view.frame non restituirà il frame di visualizzazione ruotato? quindi se è orizzontale, restituirà la cornice orizzontale, se verticale, quindi la cornice verticale, ecc. Si prega di correggermi se ho torto. – Malloc

0

Alla fine ho trovato una risposta sensata per questo. Non dovrai più scherzare con "animazioni anti-rotazione" e così via!

La chiave consiste nell'utilizzare un UIViewController per il livello di anteprima (la vista non rotante) e un altro per l'interfaccia effettiva.Configurare le opzioni di rotazione per entrambi usando shouldAutorotateToInterfaceOrientation: (il codice è nelle risposte di cui sopra):

  • Il controller anteprima vista dovrebbe essere impostato per non ruotare
  • Il controller della vista di interfaccia deve essere impostato per ruotare agli orientamenti è necessario

il bit importante è quello di mantenere le vostre opinioni a parte con l'aggiunta direttamente alla finestra. Lo faccio nella AppDelegate:

[self.window addSubview:previewViewController.view]; 
[self.window addSubview:interfaceViewController.view]; 
self.window.rootViewController = interfaceViewController; 
[self.window makeKeyAndVisible]; 

che mette il video in anteprima in sottofondo, e poi aggiunge la visualizzazione dell'interfaccia su di esso. L'interfaccia è gratuita per eseguire l'autorotazione senza influire sull'anteprima.

Una cosa importante da notare: lo sfondo della vista dell'interfaccia deve essere trasparente, altrimenti blocca l'anteprima.