2011-12-22 11 views
15

Korzystanie z Xcode 4.2.1 iPad iOS 5.0.1, utwórz nowy projekt iPada "Pojedynczy widok". W sterowniku, dodać:Po obrocie współrzędne UIView są zamieniane, ale UIWindow nie są?

- (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] ; 
} 

go uruchomić, należy obrócić urządzenie, a otrzymasz:

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} 

Innymi słowy, UIView ma swoje współrzędne „zamienione na poziomą” zgodnie z oczekiwaniami, ale jego rodzic UIWindow nadal twierdzi, że jest w trybie portretowym ...

również wielkość UIView wydaje się być nieco źle: współrzędna y, które powinny być na 20 jest w stanie 0 ...

Każdy wie WH w ten sposób?

Odpowiedz

37

Układ współrzędnych UIWindow jest zawsze w orientacji pionowej. Obraca rotację, ustawiając transformację widoku rootViewController. Na przykład utworzyłem aplikację testową za pomocą szablonu pojedynczego widoku i uruchomiłem go. W pozycji pionowej:

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

Po obróceniu lewej:

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

Po obróceniu rację

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

zauważyć jak transformaty jest (do 90 stopni macierz obrotu), gdy urządzenie jest obracane.

Odnośnie twojego pytania o rozmiar UIView: granice widoku znajdują się w jego własnej przestrzeni współrzędnych, a domyślnie miejsce pochodzenia obwiedni jest na początku (0,0) jego przestrzeni współrzędnych. Ramka widoku znajduje się w jej współrzędnej przestrzeni nadrzędnej. Możesz zobaczyć 20, których oczekiwałeś w powyższym opisie rekurencyjnym lub bezpośrednio drukując ramkę:

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

To ma sens. Dziękuję Ci. Nawiasem mówiąc, dziękuję ci również za pokazanie mi, że gdb może być faktycznie użyty interaktywnie :-) – verec

+0

@rob Poza tym, że dokumenty ref dla UIView.frame mówią: Warning Jeśli właściwość transform nie jest transformacją tożsamości, wartość tej właściwości jest niezdefiniowana dlatego należy go zignorować. Czy mógłbyś to rozwinąć? Załóżmy, że chcę animować ramkę obróconego widoku, aby przesuwać ją jako nakładkę. – tribalvibes

+1

Nie polegam na 'frame' w moim kodzie, gdy' transform' nie jest tożsamością. Jednak metoda 'frame' zawsze zwraca' [self convertRect: self.bounds toView: self.superview] 'i dlatego jest przydatna podczas debugowania. –

Powiązane problemy