2011-12-22 17 views
15

एक्सकोड 4.2.1 आईपैड आईओएस 5.0.1 का उपयोग करके, एक नया "सिंगल व्यू" आईपैड प्रोजेक्ट बनाएं। नियंत्रक में, जोड़ें:रोटेशन के बाद 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 में है पर ...

किसी क जानता है इस मतलब से?

उत्तर

37

UIWindow की समन्वय प्रणाली हमेशा पोर्ट्रेट अभिविन्यास में होती है। यह रूटव्यू कंट्रोलर के व्यू के ट्रांसफॉर्म को सेट करके रोटेशन लागू करता है। उदाहरण के लिए, मैंने एकल-दृश्य टेम्पलेट का उपयोग करके एक परीक्षण ऐप बनाया और इसे चलाया। पोर्ट्रेट ओरिएंटेशन में:

(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

समझ में आता है। धन्यवाद। संयोग से, मुझे यह दिखाने के लिए भी धन्यवाद कि जीडीबी वास्तव में इंटरैक्टिव रूप से उपयोग किया जा सकता है :-) – verec

+0

@rob यह छोड़कर कि UIView.frame के लिए रेफ डॉक्स कहते हैं: चेतावनी अगर ट्रांसफॉर्म प्रॉपर्टी पहचान ट्रांसफॉर्म नहीं है, तो इस प्रॉपर्टी का मान अपरिभाषित है और इसलिए अनदेखा किया जाना चाहिए। क्या आप इसे विस्तार से समझा सकते हैं? मान लें कि मैं इसे एक ओवरले के रूप में स्लाइड करने के लिए घुमावदार दृश्य के फ्रेम को एनिमेट करना चाहता हूं। – tribalvibes

+1

जब मैं 'ट्रांसफॉर्म' पहचान नहीं करता हूं तो मैं अपने कोड में 'फ्रेम' पर भरोसा नहीं करता हूं। हालांकि, 'फ्रेम' विधि हमेशा '[स्वयं कन्वर्ट्रैक: self.bounds toView: self.superview]' वापस आती है और इसलिए डीबगिंग के दौरान यह उपयोगी होता है। –