2011-12-22 105 views
15

使用Xcode 4.2.1 iPad iOS 5.0.1,創建一個新的「單視圖」iPad項目。在控制器中,添加:旋轉後的UIView座標交換,但UIWindow的不是?

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

運行它,旋轉設備,你會得到:

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} 

換句話說,UIView的有它的座標「換到風景」符合市場預期,但其父母的UIWindow仍然聲稱自己是在縱向模式...

此外,UIView的大小似乎稍有不妥:y座標應該是在20爲0 ...

任何人都知道WH在這個意思?

回答

37

UIWindow的座標系始終處於縱向。它通過設置其rootViewController視圖的變換來應用旋轉。例如,我使用單視圖模板創建了一個測試應用並運行它。在縱向:

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

轉動的右側後:

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

旋轉左邊後

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

通知是如何設置的轉換(成90度旋轉矩陣)時,設備旋轉。

關於你關於UIView大小的問題:一個視圖的界限在它自己的座標空間中,默認情況下視圖的界限的原點位於其座標空間的原點(0,0)處。視圖的框架位於父級的座標空間中。您可以在上面的遞歸描述中看到您期待的20個,或通過直接打印幀:

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

有意義。謝謝。順便說一句,也要感謝你給我看gdb實際上可以交互使用:-) – verec 2011-12-22 19:39:48

+0

@rob除了UIView.frame的ref文檔說:警告如果transform屬性不是標識轉換,這個屬性的值是undefined因此應該被忽略。你能詳細說明一下嗎?假設我想動畫旋轉視圖的框架以將其作爲疊加層滑動。 – tribalvibes 2012-02-12 10:04:09

+1

當'transform'不是身份時,我不會在我的代碼中依賴'frame'。然而,'frame'方法似乎總是返回'[self convertRect:self.bounds toView:self.superview]',因此它在調試時很有用。 – 2012-02-12 17:35:35