2011-12-22 13 views
15

Utilizzando Xcode 4.2.1 iPad iOS 5.0.1, creare un nuovo progetto iPad "Vista singola". Nel controllore, aggiungere:Dopo la rotazione le coordinate di UIView vengono scambiate ma quelle di UIWindow no?

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

- (void) dumpView: (UIView *) view { 
    CGRect frame = view.frame ; 
    CGRect bounds = view.bounds ; 
    CGPoint center = view.center ; 

    NSLog(@"view [%@]:%d frame=%@ bounds=%@ center=%@" 
      , NSStringFromClass(view.class) 
      , [view hash] 
      , NSStringFromCGRect(frame) 
      , NSStringFromCGRect(bounds) 
      , NSStringFromCGPoint(center)) ; 
} 

- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation) fromInterfaceOrientation { 

    NSLog(@"INViewController.didRotateFromInterfaceOrientation: %d to %d", fromInterfaceOrientation, self.interfaceOrientation) ; 
    [self dumpView: self.view] ; 
    [self dumpView: self.view.superview] ; 
} 

Run it, ruotare il dispositivo e si otterrà:

INViewController.didRotateFromInterfaceOrientation: 2 to 4 
view [UIView] bounds={{0, 0}, {1024, 748}} center={394, 512} 
view [UIWindow] bounds={{0, 0}, {768, 1024}} center={384, 512} 

In altre parole, l'UIView ha le sue coordinate "scambiato a paesaggio" come previsto, ma la sua UIWindow genitore afferma ancora di essere in modalità verticale ...

Inoltre, la dimensione UIView sembra essere leggermente sbagliato: la coordinata y che dovrebbe essere a 20 è a 0 ...

Qualcuno sa wh in questo modo?

risposta

37

Il sistema di coordinate UIWindow è sempre orientato in verticale. Applica la rotazione impostando la trasformazione della vista di rootViewController. Ad esempio, ho creato un'app di test utilizzando il modello a vista singola e l'ho eseguita. Orientamento verticale:

(gdb) po [[(id)UIApp keyWindow] recursiveDescription] 
<UIWindow: 0x9626a90; frame = (0 0; 768 1024); layer = <UIWindowLayer: 0x9626b80>> 
    | <UIView: 0x96290e0; frame = (0 20; 768 1004); autoresize = W+H; layer = <CALayer: 0x96286a0>> 

Dopo fianco rotante:

(gdb) po [[(id)UIApp keyWindow] recursiveDescription] 
<UIWindow: 0x9626a90; frame = (0 0; 768 1024); layer = <UIWindowLayer: 0x9626b80>> 
    | <UIView: 0x96290e0; frame = (0 0; 748 1024); transform = [0, 1, -1, 0, 0, 0]; autoresize = W+H; layer = <CALayer: 0x96286a0>> 

Dopo la rotazione a destra:

(gdb) po [[(id)UIApp keyWindow] recursiveDescription] 
<UIWindow: 0x9626a90; frame = (0 0; 768 1024); layer = <UIWindowLayer: 0x9626b80>> 
    | <UIView: 0x96290e0; frame = (20 0; 748 1024); transform = [0, -1, 1, 0, 0, 0]; autoresize = W+H; layer = <CALayer: 0x96286a0>> 

Si noti come la trasformata è impostato (per una matrice di rotazione di 90 gradi) quando la il dispositivo è ruotato.

Per quanto riguarda la domanda relativa alla dimensione di UIView: i limiti di una vista sono nel proprio spazio di coordinate e, per impostazione predefinita, l'origine di una vista è all'origine (0,0) del suo spazio di coordinate. La cornice di una vista si trova nello spazio delle coordinate del genitore. Potete vedere il 20 che ti aspettavi nelle descrizioni ricorsive di cui sopra, o stampando direttamente il telaio:

(gdb) p (CGRect)[[[[(id)UIApp keyWindow] subviews] lastObject] frame] 
$2 = { 
    origin = { 
    x = 0, 
    y = 20 
    }, 
    size = { 
    width = 768, 
    height = 1004 
    } 
} 
+1

ha un senso. Grazie. Per inciso, grazie anche per avermi mostrato che gdb potrebbe essere effettivamente utilizzato in modo interattivo :-) – verec

+0

@rob Tranne che i documenti di riferimento per UIView.frame dicono: Avviso Se la proprietà di trasformazione non è la trasformazione dell'identità, il valore di questa proprietà non è definito e quindi dovrebbe essere ignorato. Potresti approfondire? Supponiamo di voler animare la cornice di una vista ruotata per farla scorrere come una sovrapposizione. – tribalvibes

+1

Non mi fido di 'frame' nel mio codice quando' transform' non è l'identità. Comunque, il metodo 'frame' sembra restituire sempre' [self convertRect: self.bounds toView: self.superview] 'e quindi è utile quando si esegue il debug. –

Problemi correlati