我目前有两个UIViews:一个是红色背景,另一个是蓝色。蓝色视图是红色视图的子视图。我想做的是能够“剪掉”蓝色视图上的矩形,以便可以看到红色视图。你是如何做到的?
答案 0 :(得分:75)
您必须覆盖顶视图的drawRect
方法。因此,例如,您可以创建一个派生自HoleyView
的{{1}}类(您可以通过向项目添加新文件,选择Objective-C子类,并将“Subclass of”设置为UIView
)。在UIView
中,HoleyView
看起来像这样:
drawRect
如果您正在使用“界面”构建器,请确保将多孔视图的类更改为- (void)drawRect:(CGRect)rect {
// Start by filling the area with the blue color
[[UIColor blueColor] setFill];
UIRectFill( rect );
// Assume that there's an ivar somewhere called holeRect of type CGRect
// We could just fill holeRect, but it's more efficient to only fill the
// area we're being asked to draw.
CGRect holeRectIntersection = CGRectIntersection( holeRect, rect );
[[UIColor clearColor] setFill];
UIRectFill( holeRectIntersection );
}
。您可以通过在界面生成器中选择视图并在检查器中选择“身份”窗格(最右侧的“i”图标)来执行此操作。
您还必须使用以下代码段将顶视图设置为非透明,或者通过取消选中Interface Builder中视图属性中的HoleyView
复选框(您可以在查看视图属性的部分)并将其背景颜色的不透明度设置为0%(背景颜色在同一部分中设置)。
Opaque
如果你想做圆圈,你必须使用topView.opaque = NO;
topView.backgroundColor = [UIColor clearColor];
(又名Quartz 2D)。您可能希望阅读编程指南,该指南可用here。
要绘制椭圆而不是矩形,Core Graphics
看起来像这样:
drawRect
答案 1 :(得分:35)
所有其他答案都有道理,但很可能用清晰的颜色绘制,或者说擦除任何路径中的现有颜色,甚至使用 - [UIBezierPath fill]或类似的便捷方法。您所要做的就是根据您尝试实现的效果将上下文混合模式设置为适当的值,如下所示:
CGContextSetBlendMode(context, kCGBlendModeClear);
[[UIColor clearColor] set];
[myArbitraryPolygonPath fill];
您可以选择大约24种不同的选项,浏览CGContext reference。
答案 2 :(得分:17)
绘制椭圆而不是矩形,只需将blendMode设置为clear:
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor( context, [UIColor blackColor].CGColor );
CGContextFillRect( context, rect );
CGRect holeRectIntersection = CGRectIntersection( holeRect, rect );
CGContextSetFillColorWithColor( context, [UIColor clearColor].CGColor );
CGContextSetBlendMode(context, kCGBlendModeClear);
CGContextFillEllipseInRect( context, holeRect );
}
答案 3 :(得分:1)
这些可能是愚蠢的方式,但我不会按照你描述的方式去做,而是让它看起来像你想要的样子。
(雅克的回答刚刚出现 - 对我来说很好看)
方法1: 在视图控制器中构建一个围绕暴露的“洞”的矩形列表。随着您的洞数量的增加,平铺的数量也会增加。
方法2: 扭转你的想法。蓝色视图应位于背面,红色视图的部分位于其顶部。您仍然会看到一个红色视图,除了蓝色视图所遮盖的“洞”之外的所有视图,但您真正要做的是从您想要曝光的视图中复制区域,并在制作每个洞时将它们放在蒙版的顶部。如果您有一些模拟深度的效果,您可以根据需要添加每个孔。
既不需要子类化,也不需要drawRect:。