2012-05-23 28 views
12

कहो, मैं दो CGRects, CGRect ए और बी CGRect मेरे UIView के फ्रेम CGRect बी के रूप में ही है, लेकिन मैं UIView बीक्या फ्रेम ए से फ्रेम बी के दृश्य को बदलने के लिए आवश्यक CGAffineTransform की गणना करने का कोई तरीका है?

फ्रेम एक से संक्रमण

मैं कोशिश कर रहा हूँ दिखा एक एनीमेशन बनाना चाहते हैं UIView की ट्रांसफॉर्म प्रॉपर्टी को बदलकर ऐसा करने के लिए, इसलिए मुझे इसके फ्रेम के साथ गड़बड़ करने की ज़रूरत नहीं है। हालांकि, मुझे यह संभव बनाने के लिए CGAffineTransform की आवश्यकता है। इस परिवर्तन की गणना करने का सबसे अच्छा तरीका क्या है?

+0

क्या सीजीआरएक्ट ए से सीजीआरईटी बी से फ्रेम संपत्ति को एनिमेट करने के लिए कोई दबाव नहीं है? –

+1

दबाने नहीं। लेकिन इसका कारण यह है कि दृश्य के फ्रेम को स्थैतिक रखते हुए और इसे स्थानांतरित करने के लिए ट्रांसफॉर्म का उपयोग करके अधिक जटिल राज्य परिवर्तनों (जैसे ऑटो-रोटेशन) के दौरान इसका ट्रैक रखने में काफी सरलता होती है। – SpacyRicochet

+0

दिलचस्प दृष्टिकोण। +1 :) –

उत्तर

7

मैं इसके लिए किसी भी प्रकार की सुविधा विधि नहीं ढूंढ पा रहा हूं, इसलिए मैंने इसे प्राप्त करने के लिए कोशिश की और सही मैट्रिक्स गणनाओं का सहारा लिया।

को देखते हुए एक CGRect एक और CGRect बी, परिवर्तन एक से बी करने के लिए जाने के लिए आवश्यक गणना करने के लिए, निम्न करें:

CGAffineTransform transform = CGAffineTransformTranslate(CGAffineTransformIdentity, -A.origin.x, -A.origin.y); 
transform = CGAffineTransformScale(transform, 1/A.size.width, 1/A.size.height); 
transform = CGAffineTransformScale(transform, B.size.width, B.size.height); 
transform = CGAffineTransformTranslate(transform, B.origin.x, B.origin.y); 
1

ऊपर कोड स्निपेट में अंतिम पंक्ति के रूप में इस को बदलने की आवश्यकता:

transform = CGAffineTransformTranslate (transform, B.origin.x*A.size.width/B.size.width, B.origin.y*A.size.height/B.size.height);

26

पिछले जवाब मेरे लिए काम नहीं किया। यह काम करना चाहिए:

+ (CGAffineTransform) transformFromRect:(CGRect)sourceRect toRect:(CGRect)finalRect { 
    CGAffineTransform transform = CGAffineTransformIdentity; 
    transform = CGAffineTransformTranslate(transform, -(CGRectGetMidX(sourceRect)-CGRectGetMidX(finalRect)), -(CGRectGetMidY(sourceRect)-CGRectGetMidY(finalRect))); 
    transform = CGAffineTransformScale(transform, finalRect.size.width/sourceRect.size.width, finalRect.size.height/sourceRect.size.height); 

    return transform; 
} 

स्विफ्ट:

func transformFromRect(from: CGRect, toRect to: CGRect) -> CGAffineTransform { 
    let transform = CGAffineTransformMakeTranslation(CGRectGetMidX(to)-CGRectGetMidX(from), CGRectGetMidY(to)-CGRectGetMidY(from)) 
    return CGAffineTransformScale(transform, to.width/from.width, to.height/from.height) 
} 
+0

सबसे अच्छा स्निपेट्स में से एक जो मैंने कभी पार किया है। बहुत बढ़िया – YichenBman

3

यहाँ josema.vitaminew answer पर एक बदलाव है कि भी पहलू अनुपात पर विचार करता है (उपयोगी अगर आप वीडियो या छवियों के साथ काम कर रहे हैं):

+ (CGAffineTransform)transformFromRect:(CGRect)sourceRect toRect:(CGRect)finalRect keepingAspectRatio:(BOOL)keepingAspectRatio { 
    CGAffineTransform transform = CGAffineTransformIdentity; 

    transform = CGAffineTransformTranslate(transform, -(CGRectGetMidX(sourceRect)-CGRectGetMidX(finalRect)), -(CGRectGetMidY(sourceRect)-CGRectGetMidY(finalRect))); 

    if (keepingAspectRatio) { 
     CGFloat sourceAspectRatio = sourceRect.size.width/sourceRect.size.height; 
     CGFloat finalAspectRatio = finalRect.size.width/finalRect.size.height; 

     if (sourceAspectRatio > finalAspectRatio) { 
      transform = CGAffineTransformScale(transform, finalRect.size.height/sourceRect.size.height, finalRect.size.height/sourceRect.size.height); 
     } else { 
      transform = CGAffineTransformScale(transform, finalRect.size.width/sourceRect.size.width, finalRect.size.width/sourceRect.size.width); 
     } 
    } else { 
     transform = CGAffineTransformScale(transform, finalRect.size.width/sourceRect.size.width, finalRect.size.height/sourceRect.size.height); 
    } 

    return transform; 
} 
2

एक अच्छा स्विफ्ट 3 समाधान:

extension CGAffineTransform { 
    init(from: CGRect, toRect to: CGRect) { 
     self.init(translationX: to.midX-from.midX, y: to.midY-from.midY) 
     self = self.scaledBy(x: to.width/from.width, y: to.height/from.height) 
    } 
}