2010-04-22 12 views
14

आवेदन करते समय मुझे इस सवाल का जवाब खोजने के लिए नहीं हैरान था के बाद UIView के आकार जाओ, शायद बहुत सरल कुछ मैं किसी भी तरह की अनदेखी है:CGAffineTransform

एक UIView के वास्तविक आकार पाने के लिए कैसे के बाद मैं करने के लिए एक CGAffineTransform लागू यह?

उदाहरण के लिए।

मेरे यूआईवीव का आकार 300 x 200 है, मैं एक स्केलिंग ट्रांसफॉर्म लागू करता हूं, चलो 2 कारक क्षैतिज और ऊर्ध्वाधर दोनों कहते हैं, इसलिए UIView अब स्क्रीन पर 600 x 400 लेता है, लेकिन यह सीमा है और इसकी परत की सीमाएं अभी भी आकार लौट रही हैं 300 x 200 का ... मुझे UIView का वास्तविक आकार कहां मिल सकता है?

ps। उल्लेख करना भूल गया कि मैं uiview को घुमाने के लिए भी चाहता हूं। अगर मैं केवल स्केलिंग CGSizeApplyAffineTransform को बहुत अच्छा काम करता हूं, लेकिन जब रोटेशन भी होता है, तो यह ठीक से काम नहीं करता है।

संपादित करें: drawnonward मुझे सही दिशा में इशारा किया, मैं सिर्फ एक बिट कोड परिष्कृत संकलित करने के लिए और यहाँ यह है:

UIView* view = (your view being transformed); 
CGAffineTransform trans = (view.transform or create a new transformation); 

CGRect rect = [view bounds]; 
CGMutablePathRef path = CGPathCreateMutable(); 
rect.origin = CGPointZero; 
CGPathAddRect(path , &trans , rect); 
rect = CGPathGetBoundingBox(path); 
CGPathRelease(path); 

अब rect.size शामिल परिवर्तन के साथ देखने का आयाम लागू किया

उत्तर

11

[myView frame] लेआउट और रिश्तेदार आकारों के लिए अभिभावक द्वारा देखा गया दृश्य का फ्रेम देता है। [myView bounds] ड्राइंग के लिए, स्वयं द्वारा देखे गए दृश्य की सीमाएं देता है। यदि आपने कई विचारों पर लागू किया है, तो आप दृश्य में या convertRect: का उपयोग कर सकते हैं।

संपादित करें:

शायद ऐसा कुछ।

CGRect rect = [view bounds]; 
CGPathRef path = CGPathCreateMutable(); 
rect.origin = CGPointZero; 
CGPathAddRect(rect , [view transform]); 
rect = CGPathGetBoundingBox(path); 
CGPathRelease(path); 

उपयोग [view center] superview में स्थिति को खोजने के लिए।

+1

यहाँ सेब डॉक्स से "फ्रेम" के बारे में दस्तावेज़ है: चेतावनी: पहचान है, तो संपत्ति को बदलने नहीं बदलना, इस संपत्ति के मूल्य अपरिभाषित है और इसलिए चाहिए अनदेखा किया जाए। इसलिए, रूपांतरण लागू होने पर फ्रेम प्रश्न से बाहर है। और "सीमा" रिटर्न हमेशा मूल आकार –

+0

दरअसल! Argh, इस समारोह पुस्तकालयों कि मैं हमेशा के बारे में भूल जाते हैं - CGPathGetBoundingBox चाल थी। मैं काम कर कोड के साथ प्रश्न संपादित, बहुत बहुत शुक्रिया आदमी –

+0

भी ध्यान रखें कि केंद्र संपत्ति भी गैर पहचान बदल देती है के साथ, काम करने के लिए माना जाता है। – Olie

2

CGSizeApplyAffineTransform(size, transform) का उपयोग करें और यह एक रूपांतरित आकार लौटाएगा। इसी तरह के CGPoint और CGRect फ़ंक्शंस भी हैं।

+0

कि सही ढंग से काम नहीं कर रहा है जब CGSizeApplyAffineTransform भी रोटेशन शामिल है, लेकिन अन्यथा आप सही मामलों में वहाँ केवल स्केलिंग लागू की गई हैं। (मेरी गलती मैं भी शामिल नहीं किया था मेरे सवाल में रोटेशन) –

2

सरल:

CGSizeMake(s.width*hypotf(tr.a, tr.b), s.height*hypotf(tr.c, tr.d)) 

हालांकि, अगर दृश्य के superview या किसी पूर्वज दृश्य किसी भी गैर इकाई लागू किया बदलने है, इस का आकार: जो टीआर को बदलने के लिए साथ (सीमा) आकार रों एक दृश्य लागू किया जाता है जिसके परिणामस्वरूप आकार की है पूर्ण शर्तों में थोड़ा समझ में आता है।

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

33

मैं का उपयोग करें:

CGRect transformedBounds = CGRectApplyAffineTransform(view.bounds, view.transform); 
+0

मेरा मानना ​​है कि सिर्फ "view.bounds" एक बेहतर जवाब होगा। फ्रेम के आकार को लेने के बजाय आप यहां सीमाएं क्यों बदल रहे हैं? –

0

लेकिन अगर आप एक घूर्णन बदलने लागू होते हैं, यह CGPathGetBoundingBox द्वारा सही आकार नहीं मिलता है।

2

पुराना सवाल, लेकिन समाधान खोजने और कई प्रयासों के बाद यहां पर टक्कर लगी।यह आसान था;

view.layer.frame में सभी परिवर्तन लागू हैं और आपको आकार view.layer.frame.size से आसानी से प्राप्त होगा।

-,

और मेरी समस्या के लिए, मैं अपने घुमाया देखने के layer.anchorPoint बदलने के बाद नई center मूल्य की गणना करने की कोशिश कर रहा था, तो यह कदम नहीं करता है - - नीचे यहाँ इस प्रश्न का उत्तर नहीं है । और अंत में यह ऐसा किया;

CGPoint topLeft = [self.superview convertPoint:CGPointMake(0, 0) fromView:self]; 
self.layer.anchorPoint = CGPointMake(0, 0); 
self.center = topLeft; 

के लिए रिवर्स

CGPoint center = [self.superview convertPoint:CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2) fromView:self]; 
self.layer.anchorPoint = CGPointMake(.5, .5); 
self.center = center; 

अंत में।

संबंधित मुद्दे