UIBezierPath不会绘制圆角底角

时间:2013-04-23 09:04:58

标签: iphone ios uiview rounded-corners uibezierpath

我正试图为我的观点制作圆角并解决一个奇怪的问题。

我使用以下代码为我的视图制作圆角

bezierPath = [UIBezierPath bezierPathWithRoundedRect:btnView.bounds
                                       byRoundingCorners:UIRectCornerAllCorners
                                             cornerRadii:radius];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
    maskLayer.frame = btnView.bounds;
    maskLayer.path = bezierPath.CGPath;
    btnView.layer.mask = maskLayer;

问题是,它不适用于底角。如果我使用UIRectCornerBottomLeft没有任何反应,如果我使用UIRectCornerAllCorners,则只有顶角会被舍入。

编辑:我不使用layer.cornerRadius,因为我只想圆角。

如果我从我的视图中删除了UIViewAutoresizingFlexibleHeight自动调整遮罩,事实证明我没有问题。但我想使用autoresizing mask。有可能,如果是的如何?

我已经尝试在设置图层蒙版之前和之后设置autoresizingMask。没有运气!

9 个答案:

答案 0 :(得分:10)

我刚遇到类似的问题需要几个小时才能解决 - 答案很简单:将我的代码从viewDidLoad移到viewDidLayoutSubviews:这是自动布局完成后调用的第一个方法....所以我怀疑我确实有4个圆角但不知何故它们离屏幕边缘。

答案 1 :(得分:3)

在我得到另一个答案之前,如果可以使用UIBezierPath的autoresizingMask,我说并标记为正确的答案。

我不删除我的问题,因为任何人都可以在不知道原因的情况下解决同样的问题。

答案 2 :(得分:1)

然后使用波纹管代码代替圆角......

btnView.layer.cornerRadius = 8.0;

只需在QuartzCore/QuartzCore.h中导入.m,如下所示......

#import <QuartzCore/QuartzCore.h>

<强>更新

为此,您可以使用RoundingCorners lik bellow ....

的不同UIBezierPath属性

对于Ex:UIRectCornerBottomLeftUIRectCornerBottomRightUIRectCornerTopLeftUIRectCornerTopRightUIRectCornerAllCorners

UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect: btnView.bounds
                                               byRoundingCorners:UIRectCornerBottomLeft
                                                     cornerRadii:CGSizeMake(10.0, 10.0)];

CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = btnView.bounds;
maskLayer.path = maskPath.CGPath;
btnView.layer.mask = maskLayer;
[btnView setNeedsDisplay];

答案 3 :(得分:1)

解决方案:

-(void)roundCorners:(UIRectCorner)corner radius:(float)radius
{   
    _cornerRadius = radius;
    _corner = corner;
    [self setNeedsDisplay];
}

- (void)drawRect:(CGRect)rect {
    // Drawing code
    [super drawRect:rect];

    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:_corner cornerRadii:CGSizeMake(_cornerRadius, _cornerRadius)];

    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    maskLayer.frame = self.bounds;
    maskLayer.path = maskPath.CGPath;

    self.layer.mask = maskLayer;
}

答案 4 :(得分:1)

我认为你应该使用

bezierPath.lineCapStyle = CGLineCap.Round

答案 5 :(得分:0)

您可以使用view.layer.cornerRadius设置圆角。

已编辑:使用以下

 layer.mask = MTDContextCreateRoundedMask(layer.bounds, topleftRadius, topRightRadius, bottomLeftRadius,bottomRightRadius);

这是受支持的方法。

static inline UIImage* MTDContextCreateRoundedMask(CGRect rect, CGFloat radius_tl, CGFloat radius_tr, CGFloat radius_bl, CGFloat radius_br)
{
    CGContextRef context;
    CGColorSpaceRef colorSpace;

    colorSpace = CGColorSpaceCreateDeviceRGB();

    context = CGBitmapContextCreate( NULL, rect.size.width, rect.size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast );

    CGColorSpaceRelease(colorSpace);

    if ( context == NULL ) {
        return NULL;
    }


    CGFloat minx = CGRectGetMinX( rect ), midx = CGRectGetMidX( rect ), maxx = CGRectGetMaxX( rect );
    CGFloat miny = CGRectGetMinY( rect ), midy = CGRectGetMidY( rect ), maxy = CGRectGetMaxY( rect );

    CGContextBeginPath( context );
    CGContextSetGrayFillColor( context, 1.0, 0.0 );
    CGContextAddRect( context, rect );
    CGContextClosePath( context );
    CGContextDrawPath( context, kCGPathFill );

    CGContextSetGrayFillColor( context, 1.0, 1.0 );
    CGContextBeginPath( context );
    CGContextMoveToPoint( context, minx, midy );
    CGContextAddArcToPoint( context, minx, miny, midx, miny, radius_bl );
    CGContextAddArcToPoint( context, maxx, miny, maxx, midy, radius_br );
    CGContextAddArcToPoint( context, maxx, maxy, midx, maxy, radius_tr );
    CGContextAddArcToPoint( context, minx, maxy, minx, midy, radius_tl );
    CGContextClosePath( context );
    CGContextDrawPath( context, kCGPathFill );

    CGImageRef bitmapContext = CGBitmapContextCreateImage( context );
    CGContextRelease( context );

    UIImage *theImage = [UIImage imageWithCGImage:bitmapContext];
    CGImageRelease(bitmapContext);

    return theImage.layer.mask;
}

答案 6 :(得分:0)

不得不改变观点。由于自动调整,在viewDidLoad中无法使用底角。不得不将代码移到viewDidAppear。

-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];

CGRect bounds = self.view.bounds;
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:bounds byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerBottomLeft) cornerRadii:CGSizeMake(5.0, 5.0)];

CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = bounds;
maskLayer.path = maskPath.CGPath;
self.view.layer.mask = maskLayer;

self.view.layer.masksToBounds = YES;
[self.view setNeedsDisplay];
}

答案 7 :(得分:0)

最后我得到了成功,它确实有效。试试吧。

CGRect frame = self.accountBackgroundImage2.frame;
frame.size.height = self.view.bounds.size.height;
UIBezierPath *path=[UIBezierPath bezierPathWithRoundedRect:self.accountBackgroundImage2.bounds byRoundingCorners:(UIRectCornerBottomLeft |UIRectCornerBottomRight) cornerRadii:CGSizeMake(12.5, 12.5)];

CAShapeLayer *shapeLayer = [[CAShapeLayer alloc] init];
shapeLayer.frame = self.accountBackgroundImage2.bounds;
shapeLayer.path  = path.CGPath;
_accountBackgroundImage2.layer.mask = shapeLayer;
self.accountBackgroundImage2.frame = frame;

答案 8 :(得分:0)

另一种方式

“viewWillLayoutSubviews”中的执行

- (void)viewWillLayoutSubviews{
[self roundCornersOnView:self.buttonJoin onTopLeft:NO topRight:YES bottomLeft:YES bottomRight:NO radius:10.0];
}

功能

-(UIButton *)roundCornersOnView:(UIButton *)button onTopLeft:(BOOL)tl topRight:(BOOL)tr bottomLeft:(BOOL)bl bottomRight:(BOOL)br radius:(float)radius {

if (tl || tr || bl || br) {
    UIRectCorner corner = 0; //holds the corner
    //Determine which corner(s) should be changed
    if (tl) {
        corner = corner | UIRectCornerTopLeft;
    }
    if (tr) {
        corner = corner | UIRectCornerTopRight;
    }
    if (bl) {
        corner = corner | UIRectCornerBottomLeft;
    }
    if (br) {
        corner = corner | UIRectCornerBottomRight;
    }

    UIButton *roundedView = button;
    UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:roundedView.bounds byRoundingCorners:corner cornerRadii:CGSizeMake(radius, radius)];
    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    maskLayer.frame = roundedView.bounds;
    maskLayer.path = maskPath.CGPath;
    roundedView.layer.mask = maskLayer;
    return roundedView;
} else {
    return button;
}

}