首先,我寻找并发现了这个: Cut transparent hole in UIView 在我的视图上放置多个透明矩形,但现在我需要将这些矩形舍入,如下所示: http://postimg.org/image/ozxr0m5sh/ 所以我混合了一些代码,我发现并做到了,但由于某种原因它只适用于第一个矩形,这里是自定义视图的完整代码: (如果你取消了“addRoundedRect ...”方法,它适用于所有的rects)。
- (void)drawRect:(CGRect)rect{
[backgroundColor setFill];
UIRectFill(rect);
// clear the background in the given rectangles
for (NSValue *holeRectValue in rectsArray) {
CGRect holeRect = [holeRectValue CGRectValue];
CGRect holeRectIntersection = CGRectIntersection( holeRect, rect );
CGContextRef context = UIGraphicsGetCurrentContext();
if( CGRectIntersectsRect( holeRectIntersection, rect ) )
{
addRoundedRectToPath(context, holeRectIntersection, 6, 6);
CGContextClosePath(context);
CGContextClip(context);
CGContextClearRect(context, holeRectIntersection);
CGContextSetFillColorWithColor( context, [UIColor clearColor].CGColor );
CGContextFillRect( context, holeRectIntersection);
}
}
static void addRoundedRectToPath(CGContextRef context, CGRect rect, float ovalWidth, float ovalHeight){
float fw, fh;
if (ovalWidth == 0 || ovalHeight == 0) {
CGContextAddRect(context, rect);
return;
}
CGContextSaveGState(context);
CGContextTranslateCTM (context, CGRectGetMinX(rect), CGRectGetMinY(rect));
CGContextScaleCTM (context, ovalWidth, ovalHeight);
fw = CGRectGetWidth (rect) / ovalWidth;
fh = CGRectGetHeight (rect) / ovalHeight;
CGContextMoveToPoint(context, fw, fh/2);
CGContextAddArcToPoint(context, fw, fh, fw/2, fh, 1);
CGContextAddArcToPoint(context, 0, fh, 0, fh/2, 1);
CGContextAddArcToPoint(context, 0, 0, fw/2, 0, 1);
CGContextAddArcToPoint(context, fw, 0, fw, fh/2, 1);
CGContextClosePath(context);
CGContextRestoreGState(context);
}
答案 0 :(得分:1)
在iOS中,最好不要使用drawRect。它往往比其他渲染内容的方法慢。
我不知道你的问题的具体答案,为什么你可以在你的视图中打出多个圆形孔,但我建议采用不同的方法。而不是在drawRect方法中使用CGContexts。
使用您需要的任何内容设置视图。然后创建一个与视图大小相同的CAShapeLayer并用路径填充它(形状图层需要一个CGPath,但你可以创建一个UIBezierPath并从中获得一个CGPath。)将形状图层作为视图的掩码附加' s层。 (放在遮罩层中的形状定义了视图的不透明部分,因此您必须创建一个填充遮罩的形状,然后在其中打孔以及其他形状。
答案 1 :(得分:0)
这里我有一个裂缝。必须在此视图上关闭UserInteraction才能传递触摸事件,因此请不要在此处添加任何子视图,除非您希望它们也忽略触摸...
接口:
#import "AslottedView.h"
//header is empty but for #import <UIKit/UIKit.h>
//this is a subclass on UIView
@interface AslottedView ()
//helper function, nb resultantPath will rerquire releasing(create in func name)
CGMutablePathRef CGPathCreateRoundedRect(CGRect rect, CGFloat cornerRadius);
@end
实现:
@implementation AslottedView
{
CGRect slots[4];
}
CGMutablePathRef CGPathCreateRoundedRect(CGRect rect, CGFloat cornerRadius){
CGMutablePathRef result = CGPathCreateMutable();
CGPathMoveToPoint(result, nil, CGRectGetMinX(rect)+cornerRadius, (CGRectGetMinY(rect)) );
CGPathAddArc(result, nil, (CGRectGetMinX(rect)+cornerRadius), (CGRectGetMinY(rect)+cornerRadius), cornerRadius, M_PI*1.5, M_PI*1.0, 1);//topLeft
CGPathAddArc(result, nil, (CGRectGetMinX(rect)+cornerRadius), (CGRectGetMaxY(rect)-cornerRadius), cornerRadius, M_PI*1.0, M_PI*0.5, 1);//bottomLeft
CGPathAddArc(result, nil, (CGRectGetMaxX(rect)-cornerRadius), (CGRectGetMaxY(rect)-cornerRadius), cornerRadius, M_PI*0.5, 0.0, 1);//bottomRight
CGPathAddArc(result, nil, (CGRectGetMaxX(rect)-cornerRadius), (CGRectGetMinY(rect)+cornerRadius), cornerRadius, 0.0, M_PI*1.5, 1);//topRight
CGPathCloseSubpath(result);
return result;
}
CGColorRef fillColor(){
return [UIColor whiteColor].CGColor;
//or whatever..
}
-(instancetype )initWithFrame:(CGRect)frame{
if (self = [super initWithFrame:frame]) {
self.userInteractionEnabled = NO;
self.backgroundColor = [UIColor clearColor];
//quick loop to make some rects
CGRect rct = CGRectMake(10.0, 10.0, 40.0, 40.0);
CGFloat margin = 30.0;
for (NSInteger i = 0; i < 4; i ++) {
slots[i] = CGRectOffset(rct, ((rct.size.width+margin) * ((i%2==0)? 1.0 : 0.0)) , ((rct.size.height+margin) * ((i>1)? 1.0:0.0) )) ;
}
}
return self;
}
- (void)drawRect:(CGRect)rect {
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(ctx, fillColor() );
CGContextAddRect(ctx, self.bounds);
for (NSInteger i = 0; i < 4; i ++) {
CGMutablePathRef roundRect = CGPathCreateRoundedRect(slots[i], 5.0);
CGContextAddPath(ctx, roundRect);
CGPathRelease(roundRect);
}
CGContextEOFillPath(ctx);
}
@end