2014-07-04 104 views
1

我有一個CALayer與多個子層。 clipsToBoundsNO(默認)。我想將CALayer(包括所有子圖層)的完整內容繪製到圖像上下文中。爲此我需要確定上下文需要多大。 CALayer有沒有一種方法來檢索圖形上下文所需的大小,以適應所有內容? (即超出圖層邊界的內容)查找CALayer的邊界框繪製到圖形上下文

回答

3

可以計算邊框作爲層的工會及其所有子層。

CGRect boundingBox = myLayer.bounds; 
for (CALayer *sublayer in myLayer.sublayers) { 
    boundingBox = CGRectUnion(boundingBox, sublayer.frame); 
} 

這工作,因爲CGRectUnion回報:

完全包含在源矩形的最小矩形。

所以通過做邊界框和每個層的聯合,你得到一個矩形是最小的矩形,它完全包含所有的子層(和圖層本身)。


注意,bounds用於該層本身,同時frame用於該子層。這是因爲邊界在層自己的座標系中,而框架在父系座標系中。這意味着子層上的幀位於myLayer的座標系中。

另外請注意,這不是一個遞歸解決方案,所以如果子層有自己的超出邊界範圍的子層,那麼這個解決方案將不會解決這個問題。

+0

這比我的想法好多了!清晰而簡單。 – justMartin

+0

@DavidRönnqvist:假設有一個UIImageView小於它的圖像,而視圖的內容模式設置爲UIViewContentModeCenter。如果maskToBounds設置爲NO,那麼上面的答案會錯誤地報告UIImageView的邊界,並且圖像會被剪切? – camimvogelsang

+0

@camimvogelsang是一個問題或聲明? –

1

否 - 圖形上下文沒有大小,所以沒有這種方法。你必須自己做。 您需要迭代所有子圖層,並查找寬度/高度的所有最小值;

你需要類似的東西:

CGRect layerRect = [self layer].frame; 

CGFloat minX = CGRectGetMinX(layerRect); 
CGFloat maxX = CGRectGetMaxX(layerRect); 
CGFloat minY = CGRectGetMinY(layerRect); 
CGFloat maxY = CGRectGetMaxY(layerRect); 

for(CALayer *sublayer in [[self layer] sublayers]) 
{ 
    CGRect sublayerRect = sublayer.frame; 

    minX = MIN(minX, CGRectGetMinX(sublayerRect)); 
    maxX = MAX(maxX, CGRectGetMaxX(sublayerRect)); 

    minY = MIN(minY, CGRectGetMinY(sublayerRect)); 
    maxY = MAX(maxY, CGRectGetMinY(sublayerRect)); 
} 

CGSize imageSize = (CGSize){maxX - minX, maxY - minY}; 
+0

就像'bounds'一樣,'frame'不會給出內容的實際邊界框。考慮一個'CALayer',其內容流出'bounds','clipToMask'設置爲'NO'。 – camimvogelsang

+0

這就是我的答案。 – justMartin