UIView有透明的圆角矩形?

时间:2015-02-07 02:30:46

标签: ios objective-c uiview rounded-corners

首先,我寻找并发现了这个: 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);
}

2 个答案:

答案 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