2010-04-19 6 views
21

Problemi di ottenere i limiti corretti per l'applicazione iPad quando la si avvia in modalità orizzontale. Ho i tasti corretti impostati nel mio file Info.plist e i miei controller di visualizzazione si avviano correttamente in orizzontale (e verticale, natch).UIScreen applicationFrame che restituisce rettangolo errato all'avvio dell'applicazione landscape (iPhone/iPad)

Nel mio metodo applicationDidFinishLaunching: Chiamo un selettore, dopo un ritardo di 3 secondi, e che il metodo effettua una chiamata a [[UIScreen mainScreen] applicationFrame], ma mi sta restituendo un telaio verticale (cioè altezza> larghezza).

Qualcuno sa come risolvere questo problema? Mi sembri un insetto (in tal caso inserirò un radar), ma se è un comportamento previsto, dove è documentato?

+16

Posso solo dire "incorrectangle" d'ora in poi? – jbrennan

risposta

6

Quando si tiene l'iPad in orientamento orizzontale e si avvia un'applicazione, inizialmente il controller della vista vede i limiti per una vista verticale (anche se i rapporti di orientamento sono orizzontali). Il controller della vista quindi otterrà un messaggio da ruotare sull'orientamento orizzontale prima che appaia.

+0

Quindi, dopo che il messaggio è stato inviato al controller della vista per ruotare, il sistema di coordinate rifletterà il nuovo orientamento? Ad esempio, dopo che il messaggio è stato inviato, larghezza> altezza? –

5

Questo è come progettato. Dovresti interrogare la dimensione della tua superview e regolarla secondo necessità.

+0

Puoi spiegare perché questo è stato progettato in questo modo (o almeno come speculare). Mi sembra illogico dare dei limiti errati per lo schermo se è stato ruotato. Il 'superview' in questione è la finestra della mia applicazione (e ho provato ad usare anche la sua cornice con gli stessi risultati). – jbrennan

+0

Il motivo è che le finestre possono essere ruotate indipendentemente dallo schermo. Esempio: quando un'applicazione di ritratto avvia un video di YouTube, la finestra principale rimane verticale, ma una finestra orizzontale viene animata sopra di essa. Durante l'animazione, il dispositivo dovrebbe essere considerato ritratto o paesaggio? (l'orientamento dell'accelerometro è separato dall'orientamento della finestra è separato dall'orientamento della barra di stato) – rpetrich

+0

Ho notato anche questo, è davvero strano. Grazie per il testa a testa. – Justin

35

Non mi affido mai allo [[UIScreen mainScreen] applicationFrame], in particolare durante l'avvio dell'app.

Quando si creano viste nel codice, utilizzare la superview per impostare la cornice.

Se si utilizzano xibs con "elementi di interfaccia simulati", verranno ridimensionati correttamente e tutto funzionerà perfettamente.

UINavigationController basato applicazioni

Nel caso di un'applicazione UINavigationController base, afferrare il telaio direttamente da self.navigationController.view, non tentare di utilizzare [self loadView] e self.view.superview. UINavigationController utilizza le sottoview "nascoste" per eseguire il proprio lavoro, quindi la superview diretta non funzionerà.

UINavigationController è speciale perché durante l'avvio dell'app, il controller di navigazione ridimensiona le visualizzazioni dopo che loadView viene richiamato. Quando l'autoresizing si attiva, si finisce con un piccolo margine nella parte inferiore dello schermo.

Perché non UIScreen

[[UIScreen mainScreen] applicationFrame] non funziona in modo affidabile (soprattutto durante il lancio di app nel paesaggio). La mia esperienza è che la proprietà interfaceOrientation del viewcontroller non corrisponderà all'orientamento applicationFrame.

+0

Questo è così importante! Grazie – coco

+0

Questo è molto utile! Se l'avessi trovato prima, avrei risparmiato un sacco di tempo! Grazie! – coder284

6

Questo è il modo in cui ricevo il CGRect corretta quando il controller della vista è sul paesaggio:

CGRect landscapeBounds; 
if (self.view.frame.size.width < self.view.frame.size.height) 
    landscapeBounds = CGRectMake(self.view.frame.origin.y, self.view.frame.origin.x, self.view.frame.size.height, self.view.frame.size.width); 
else 
    landscapeBounds = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, self.view.frame.size.height); 
0

ho ottenuto in stesso problema quando respinge vista con dismissViewControllerAnimated a Cordova plugin. ho modificato il codice per il metodo singingAtom viewWillAppear in MainViewController, che ha ottenuto ridimensionata dopo che respinge vista modale:

- (void)viewWillAppear:(BOOL)animated 
    { 
    CGRect appFrame = [[UIScreen mainScreen] applicationFrame]; 
    UIDeviceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; 
    if (UIDeviceOrientationLandscapeLeft == orientation || 
     UIDeviceOrientationLandscapeRight == orientation) 
      { 
      if (appFrame.size.width < appFrame.size.height) 
       { 
       appFrame = CGRectMake(appFrame.origin.y, appFrame.origin.x, appFrame.size.height, appFrame.size.width); 
       } 
     } 
    self.view.frame = appFrame; 
    [super viewWillAppear:animated]; 
} 
14
CGRect bounds = [[UIScreen mainScreen] bounds]; // portrait bounds 
if (UIInterfaceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation])) { 
    bounds.size = CGSizeMake(bounds.size.height, bounds.size.width); 
} 
1

Quindi, aggiungere un'immagine di lancio e dargli la -568h suffisso, secondo le guide di Apple.

Non capisco perché chiunque abbia una mente sana possa fare in modo che le impostazioni del sistema dipendano da un grafico; ma ho appena testato e ha funzionato.

Here is the spot that taught me after a quick search Non ho visto questa risposta sopra, ho pensato che sarebbe stato utile a qualcuno.

S

2

[[UIScreen mainScreen] applicationFrame] restituirà sempre il rettangolo ritratto, anche se l'applicazione è in modalità orizzontale. Ciò è correlato al fatto che lo UIWindowmai ruota effettivamente ma modifica semplicemente la trasformazione di rootViewController.view.

Per essere sicuri, è possibile stampare l'oggetto vista radici in modalità verticale e orizzontale, e vedrete qualcosa di simile:

Ritratto:

<UIView: 0x96290e0; frame = (0 20; 768 1004); ... 

Paesaggio:

<UIView: 0x96290e0; frame = (0 20; 768 1004); transform = [0, 1, -1, 0, 0, 0]; ...