根据子视图所在的位置从 UIView 中屏蔽特定像素

Posted

技术标签:

【中文标题】根据子视图所在的位置从 UIView 中屏蔽特定像素【英文标题】:Mask out specific pixels from a UIView based on where subviews are located 【发布时间】:2014-03-20 21:55:37 【问题描述】:

假设我有一个主 UIView,它有几个 CatView 和 DogView 类型的子视图。我想将此 UIView 渲染为图像,但我想排除 DogViews,以便最终渲染的图像具有透明像素来代替任何 DogView。 (请注意,简单地从视图中删除 DogViews 是行不通的——我需要 DogViews 所在的透明像素)。此外,DogView 可以旋转,因此它们不一定占据视图的矩形部分。

有什么想法可以解决这个问题吗?

编辑:第一次尝试

- (UIImage *)createCutOutViewFromView:(UIView*)view 

    UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0.0);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextMoveToPoint(context, 200, 200);
    CGContextAddLineToPoint(context, 250, 200);
    CGContextAddLineToPoint(context, 250, 250);
    CGContextAddLineToPoint(context, 200, 250);
    CGContextClosePath(context);

    CGContextClip(context);

    [view.layer renderInContext:context];

    UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return result;


结果是我只能看到我裁剪的 50px 矩形。我真的想看看除了这个矩形之外的所有东西。有什么建议吗?

编辑:第二次尝试

- (UIImage *)createCutOutViewFromView:(UIView*)view 

    UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0.0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextClearRect(context, view.bounds);

    [view.layer renderInContext:context];

    UIBezierPath* path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(200, 200)];
    [path addLineToPoint:CGPointMake(250, 200)];
    [path addLineToPoint:CGPointMake(250, 250)];
    [path addLineToPoint:CGPointMake(200, 250)];
    [path closePath];

    [path fillWithBlendMode:kCGBlendModeNormal alpha:0.0];


    UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();


    return result;


【问题讨论】:

啊,那是缠绕规则。尝试逆时针绘制。 嗯。如果我逆时针绘制,仍然只得到小矩形。 这很奇怪。我一直在寻找缠绕规则的解释,我想我想出了一个更简单的解决方案。我会更新我的答案。 参见编辑 2。现在什么都没有删减。我必须使用某种混合模式吗? 试试 kCGBlendModeClear。 【参考方案1】:

创建一个位图图形上下文并将视图渲染到该上下文中。然后为每个 DogView 创建一个 UIBezierPath,并使用 moveToPointaddLineToPointclosePath 绘制 DogView 所在位置的轮廓。然后调用 alpha 为 0.0 的 fillWithBlendMode:alpha: 以清除绘图的该区域。

我喜欢使用UIGraphicsBeginImageContext 来创建位图图形上下文,因为它只需要一个大小,您可以从视图的边界获得它。这是一般框架。

UIGraphicsBeginImageContext( view.bounds.size );
CGContextRef context = UIGraphicsGetCurrentContext();

// drawing stuff goes here

UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

【讨论】:

这听起来不错。如果我不能让它工作,我会试一试并在这里发布代码。 我使用 CGBitmapContextCreate 吗?开始时正确的参数是什么? @soleil 我已经更新了答案,让你有一点先见之明。

以上是关于根据子视图所在的位置从 UIView 中屏蔽特定像素的主要内容,如果未能解决你的问题,请参考以下文章

iOS UIView 不调整子视图的大小?

UIView常见属性二

如何获取 UIView 中特定子视图的计数?

将捏合手势从自定义 UIView 传递到父 UIScrollView

从 Xcode 视图调试中找出视图代码的位置

在 Hive 视图中屏蔽子字符串