2015-02-07 280 views
0

首先,我看过了,发现这个: Cut transparent hole in UIView 把我的看法多个透明的长方形,但现在我需要这些矩形变圆,就像这样: http://postimg.org/image/ozxr0m5sh/ 所以我混的一些代码,我发现和这样做,但由于某种原因,它只适用于第一个矩形,下面是自定义视图的完整代码: (如果您取消方法“addRoundedRect ...”调用,它适用于所有矩形)。带有透明圆角矩形的UIView?

- (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

这里我有一个裂缝。用户交互必须在这个视图,以便通过通过触摸事件,所以在这里,除非你想让他们忽略触摸以及不添加任何子视图被关闭..

接口:

#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 
1

在iOS中通常最好不要使用drawRect。它往往比渲染你的内容的其他方法慢。

我不知道你的问题的具体答案,你为什么不能在你的视图中打多个圆边的孔,但我会建议采用不同的方法。比在drawRect方法中使用CGContexts更方便。

用您需要的任何内容设置您的视图。然后创建一个与视图大小相同的CAShapeLayer并填充一个路径(形状图层需要CGPath,但是可以创建UIBezierPath并从中获取CGPath)。将形状图层作为视图图层的蒙版。 (然而,你在掩模图层中放置的形状定义了视图的不透明部分,但是,因此必须创建一个填充掩模的形状,然后用其他形状在其中打孔。