2011-12-22 20 views
15

Usando Xcode 4.2.1 iPad iOS 5.0.1, cree un nuevo proyecto iPad de "Vista única". En el controlador, añadir:Después de la rotación, ¿las coordenadas de UIView se intercambian pero las de 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] ; 
} 

ejecutarlo, girar el dispositivo y obtendrá:

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} 

En otras palabras, el UIView tiene sus coordenadas "intercambiado con el paisaje" como se esperaba, pero su UIWindow padre todavía dice que está en el modo de retrato ...

Además, el tamaño UIView parece ser un poco mal: la coordenada y que debería estar en 20 a 0 ... es

Cualquiera sabe WH en este medio?

Respuesta

37

El sistema de coordenadas de la UIWindow está siempre en orientación vertical. Aplica la rotación configurando la transformación de su vista de rootViewController. Por ejemplo, creé una aplicación de prueba usando la plantilla de vista única y la ejecuté. En la orientación vertical:

(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>> 

Después de izquierda rotación:

(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>> 

Después de girar a la derecha:

(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>> 

Aviso cómo se establece la transformada de (a una matriz de rotación de 90 grados) cuando el el dispositivo está girado.

Respecto a su pregunta sobre el tamaño de UIView: los límites de una vista están en su propio espacio de coordenadas, y por defecto el origen de los límites de una vista está en el origen (0,0) de su espacio de coordenadas. El marco de una vista está en el espacio de coordenadas de sus padres. Puede ver los 20 que esperaba en las descripciones recursivas anteriores, o al imprimir el marco directamente:

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

Tiene sentido. Gracias. Por cierto, gracias también por mostrarme que gdb podría usarse interactivamente :-) – verec

+0

@rob Excepto que los documentos de referencia para UIView.frame dicen: Advertencia: si la propiedad de transformación no es la transformación de identidad, el valor de esta propiedad no está definido y por lo tanto debe ser ignorado. ¿Podrías profundizar en eso? Supongamos que quiero animar el marco de una vista girada para deslizarlo como una superposición. – tribalvibes

+1

No confío en 'frame' en mi código cuando' transform' no es la identidad. Sin embargo, el método 'frame' parece siempre devolver' [self convertRect: self.bounds toView: self.superview] 'y así es útil cuando se depura. –

Cuestiones relacionadas