【问题标题】:Find bounding box for CALayer to draw into graphics context查找 CALayer 的边界框以绘制到图形上下文中
【发布时间】:2014-07-04 10:32:02
【问题描述】:

我有一个带有多个子层的CALayerclipsToBoundsNO(默认)。我想将CALayer(包括所有子层)的完整内容绘制到图像上下文中。为此,我需要确定上下文需要有多大。 CALayer 上是否有一种方法可以检索图形上下文所需的大小,以适应所有内容? (即超出层边界的内容)

【问题讨论】:

    标签: ios core-graphics core-animation


    【解决方案1】:

    您可以将边界框计算为图层及其所有子图层的并集。

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

    这是因为CGRectUnion 返回:

    完全包含两个源矩形的最小矩形。

    所以通过合并边界框和每一层,你得到一个矩形是完全包含所有子层(和层本身)的最小矩形。


    请注意,bounds 用于图层本身,而frame 用于子图层。这是因为边界在图层自己的坐标系中,而框架在父坐标系中。这意味着子图层上的帧位于myLayer 的坐标系中。

    另请注意,这不是递归解决方案,因此如果子层在其范围之外有自己的子层,则此解决方案不会解决此问题。

    【讨论】:

    • 这比我的想法好得多!清晰简单。
    • @David Rönnqvist:假设有一个小于其图像的 UIImageView,并且视图的内容模式设置为 UIViewContentModeCenter。如果 maskToBounds 设置为 NO,您上面的答案会错误地报告 UIImageView 的边界并且图像会被剪裁?!
    • @camimvogelsang 这是一个问题还是一个声明?
    • @DavidRönnqvist:对不起,是的,这是一个问题。似乎按照您的建议计算框架/边界的联合会导致错误的边界框,因为它没有考虑maskToBounds=NO?或者换一种说法,当maskToBounds=NO 时,你将如何计算没有任何子层的单层的边界框。当添加到图层层次结构时,图层边界之外的区域将是可见的,但似乎会被上述边界框计算剪裁。
    • @camimvogelsang 这与您最初的问题完全不同。你到底是怎么画出界限的?这可能更适合新问题(将链接回该问题)
    【解决方案2】:

    否 - 图形上下文没有大小,因此没有这种方法。你必须自己做。 您需要遍历所有子层并找到宽度/高度的所有最大值和最小值;

    你需要这样的东西:

    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};
    

    【讨论】:

    • bounds 一样,frame 不会给出内容的实际边界框。想想CALayer,其中内容流出bounds,而clipToMask 设置为NO
    • 这正是我的回答中发生的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    • 2011-06-05
    • 2020-11-29
    • 1970-01-01
    相关资源
    最近更新 更多