2011-09-25 88 views
3

我在x和y方向上用因子2縮放UIBezierPath(由一個[0,0 - 1x1]矩形構建)。 UIBezierPath 「.bounds」 是正常的(即如預期比例),而 「.CGPath」 保持不變...關於UIBezierPath + applyTransform + CGPath的困惑

代碼:

#import <UIKit/UIKit.h> 

int main(int argc, char *argv[]) 
{ 
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, 
                    1, 1)]; 
    NSLog(@"path.bounds box before transform:%@", 
      NSStringFromCGRect(path.bounds)); 
    NSLog(@"path.CGPath box before transform:%@", 
      NSStringFromCGRect(CGPathGetBoundingBox(path.CGPath))); 

    [path applyTransform:CGAffineTransformMakeScale(2, 2)]; 

    NSLog(@"path.bounds box after transform:%@", 
      NSStringFromCGRect(path.bounds)); 
    NSLog(@"path.CGPath box after transform:%@", 
      NSStringFromCGRect(CGPathGetBoundingBox(path.CGPath))); 

    return 0;   
} 

輸出:

path.bounds box before transform:{{0, 0}, {1, 1}} 
path.CGPath box before transform:{{0, 0}, {1, 1}} 
path.bounds box after transform:{{0, 0}, {2, 2}} 
path.CGPath box after transform:{{0, 0}, {1, 1}} 

爲什麼?

回答

4

這種差異的原因是因爲applyTransform的調用只是將變換矩陣存儲在路徑對象中。它不會導致路徑本身被修改。 path.bounds是使用transform導出的計算屬性,而CGPathGetBoundingBox調用只是遍歷傳入的CGPath對象的元素。

因爲可能存在大量路徑元素,所以存儲變換矩陣,而不是每次分配新矩陣時都修改所有路徑元素,這是作爲優化來完成的。只有在查詢UIBezierPath的某些屬性(例如邊界)時,才能完成此工作,或者最低限度地完成此工作。

7

從iOS 5.1開始,CGPathUIBezier返回的.CGPath屬性確實在UIBezierPath應用了新轉換時更新。

但是,這並不排除舊版iOS的解決方案。您可以從UIBezierPath中獲得CGPath,直接對其進行轉換,然後將其設置回UIBezierPath。瞧,所有其他屬性,如界限和來源,都會立即正確更新。

UIBezierPath* path = [UIBezierPath bezierPathWithRect:CGRectMake(0.0f, 0.0f, 
                   1.0f, 1.0f)]; 

CGAffineTransform transform = CGAffineTransformMakeScale(2.0f, 2.0f); 
CGPathRef intermediatePath = CGPathCreateCopyByTransformingPath(path.CGPath, 
                   &transform); 

path.CGPath = intermediatePath; 

CGPathRelease(intermediatePath); 
+0

此代碼導致嚴重的內存泄漏。 –

+1

感謝您指出這一點;的確如此。我忘了添加'CGPathRelease(intermediatePath);'來釋放你擁有的臨時文件。 –