How to make a UIView with optional rounded corners

2020-02-10 10:25发布

问题:

I am applying corner radius to a UIView i.e. UIRectCornerTopLeft and UIRectCornerTopRight. When I apply this, the border is gone at the corners. How to avoid this?

This is how I apply border to UIView:

 [self.middleView addRoundedCorners:UIRectCornerTopLeft|UIRectCornerTopRight withRadii:CGSizeMake(4, 4)];
 self.middleView.layer.borderWidth = 0.5f;
 self.middleView.layer.borderColor = [[UIColor colorWith8BitRed:0 green:0 blue:0 alpha:0.25]

And this is a category I am using for applying optional rounded corners:

   #import "UIView+Roundify.h"

   @implementation UIView (Roundify)
  - (void)addRoundedCorners:(UIRectCorner)corners withRadii:(CGSize)radii {
   CALayer *tMaskLayer = [self maskForRoundedCorners:corners withRadii:radii];
   self.layer.mask = tMaskLayer;
   }

  - (CALayer*)maskForRoundedCorners:(UIRectCorner)corners withRadii:(CGSize)radii {
    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    maskLayer.frame = self.bounds;

  UIBezierPath *roundedPath = [UIBezierPath bezierPathWithRoundedRect:
                             maskLayer.bounds byRoundingCorners:corners cornerRadii:radii];
    maskLayer.fillColor = [[UIColor whiteColor] CGColor];
    maskLayer.backgroundColor = [[UIColor clearColor] CGColor];
    maskLayer.path = [roundedPath CGPath];

   return maskLayer;
 }

回答1:

Try below code it work

Your view which you want to rounded TopLeft and TopRight

   UIView *view1 = [[UIView alloc]initWithFrame:CGRectMake(50, 100, 100, 100)];
   [view1 setBackgroundColor:[UIColor grayColor]];
   [self.view addSubview:view1];

Set Corner as below code

UIBezierPath *maskPath;
maskPath = [UIBezierPath bezierPathWithRoundedRect:view1.bounds byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight) cornerRadii:CGSizeMake(5.0, 5.0)];

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

OUTPUT IS:



回答2:

Found this piece of code. Have not actually tried it, but seems like it is what you need.

- (void)drawDashedBorderAroundView:(UIView *)v {

    //border definitions
    CGFloat cornerRadius = 10;
    CGFloat borderWidth = 2;
    NSInteger dashPattern1 = 8;
    NSInteger dashPattern2 = 8;
    UIColor *lineColor = [UIColor orangeColor];

    //drawing
    CGRect frame = v.bounds;

    CAShapeLayer *_shapeLayer = [CAShapeLayer layer];

    //creating a path
    CGMutablePathRef path = CGPathCreateMutable();

    //drawing a border around a view
    CGPathMoveToPoint(path, NULL, 0, frame.size.height - cornerRadius);
    CGPathAddLineToPoint(path, NULL, 0, cornerRadius);
    CGPathAddArc(path, NULL, cornerRadius, cornerRadius, cornerRadius, M_PI, -M_PI_2, NO);
    CGPathAddLineToPoint(path, NULL, frame.size.width - cornerRadius, 0);
    CGPathAddArc(path, NULL, frame.size.width - cornerRadius, cornerRadius, cornerRadius, -M_PI_2, 0, NO);
    CGPathAddLineToPoint(path, NULL, frame.size.width, frame.size.height - cornerRadius);
    CGPathAddArc(path, NULL, frame.size.width - cornerRadius, frame.size.height - cornerRadius, cornerRadius, 0, M_PI_2, NO);
    CGPathAddLineToPoint(path, NULL, cornerRadius, frame.size.height);
    CGPathAddArc(path, NULL, cornerRadius, frame.size.height - cornerRadius, cornerRadius, M_PI_2, M_PI, NO);

    //path is set as the _shapeLayer object's path
    _shapeLayer.path = path;
    CGPathRelease(path);

    _shapeLayer.backgroundColor = [[UIColor clearColor] CGColor];
    _shapeLayer.frame = frame;
    _shapeLayer.masksToBounds = NO;
    [_shapeLayer setValue:[NSNumber numberWithBool:NO] forKey:@"isCircle"];
    _shapeLayer.fillColor = [[UIColor clearColor] CGColor];
    _shapeLayer.strokeColor = [lineColor CGColor];
    _shapeLayer.lineWidth = borderWidth;
    _shapeLayer.lineDashPattern = [NSArray arrayWithObjects:[NSNumber numberWithInt:dashPattern1], [NSNumber numberWithInt:dashPattern2], nil];
    _shapeLayer.lineCap = kCALineCapRound;

    //_shapeLayer is added as a sublayer of the view, the border is visible
    [v.layer addSublayer:_shapeLayer];
    v.layer.cornerRadius = cornerRadius;
}

This piece of code adds a dashed line, but you can modify that by _shapeLayer.lineDashPattern.



回答3:

Unless there is some specific requirement which we're not aware of, the bezier path and mask are unnecessary if all you're trying to do is round the corners and have a border. I would normally just do this: myView.layer.borderWidth=2; myView.layer.cornerRadius=5;

Is it that you only want the top corners rounded that you need to not use the layer rounding? If so, why not use that and then overlay a thin view to cover the bottom bit? A bit fiddly, but I find that the more you can rely on the standard controls to draw themselves rather than having to step into core graphics, the better.

Edit: ok, given that it needs to have the bottom corners not rounded, how about if you had a category on UIView with 2 subviews: 1 with 4 rounded corners and another layed over the top (self bringSubviewToFront) which simply covers the rounded view's "footer" with a non-rounded strip, ie a view with equal width and tiny height which is equal to the rounded corner radius. If you have a solid color background then just make both subviews the same; if you have some texture or image background, make them both transparent and put the texture/image on the super view (the parent view who is using your category's specific layout method). Then finally, put the border on that same superview. Should work, let me know what you think.