Round top corners of a UIView and add border

前端 未结 4 484
自闭症患者
自闭症患者 2020-12-03 01:55

I have the following code in a category that does rounding of corners. I would also like to draw a border. But the border is not shown on the rounded part of the corner.

相关标签:
4条回答
  • 2020-12-03 02:17
          label.layer.cornerRadius = 3.0 
         label.layer.maskedCorners = [.layerMinXMinYCorner,.layerMinXMaxYCorner]//round top left and bottom left corners
    

    Source:https://www.hackingwithswift.com/example-code/calayer/how-to-round-only-specific-corners-using-maskedcorners

    Image of working solution

    0 讨论(0)
  • 2020-12-03 02:18

    this is probably a very late answer but I would just like to share the solution I came up with based on answers of different people from different similar questions. I got big help from Vojtech's answer above.

    extension UIView {
        func EZRoundCorners(corners:UIRectCorner, radius: CGFloat) -> CAShapeLayer {
            let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
            let mask = CAShapeLayer()
            mask.path = path.CGPath
            self.layer.mask = mask
            return mask
        }
    
        func EZRoundCornersWithBorder(corners:UIRectCorner, radius:CGFloat, color:UIColor, width:CGFloat) -> CAShapeLayer {
    
            let mask = self.EZRoundCorners(corners, radius: radius)
    
            // Add border
            let borderLayer = EZCALayer()
            borderLayer.path = mask.path // Reuse the Bezier path
            borderLayer.fillColor = UIColor.clearColor().CGColor
            borderLayer.strokeColor = color.CGColor
            borderLayer.lineWidth = width
            borderLayer.frame = self.bounds
            self.layer.addSublayer(borderLayer)
            return borderLayer
        }
    
        func removeEZLayers () {
            for layer in self.layer.sublayers! {
                if layer is EZCALayer {
                    layer.removeFromSuperlayer()
                }
            }
        }
    }
    
    class EZCALayer : CAShapeLayer {
    }
    

    I inherited from CAShapeLayer so I can remove the border sublayers if I don't want to use them anymore.

    0 讨论(0)
  • 2020-12-03 02:20

    The mask layer doesn't get drawn, just used to compute the mask. Try:

    -(void)roundCorners:(UIRectCorner)corners radius:(CGFloat)radius
    {
        CGRect bounds = self.bounds;
        UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:bounds
                                                       byRoundingCorners:corners
                                                             cornerRadii:CGSizeMake(radius, radius)];
    
        CAShapeLayer *maskLayer = [CAShapeLayer layer];
        maskLayer.frame = bounds;
        maskLayer.path = maskPath.CGPath;
    
        self.layer.mask = maskLayer;
    
        CAShapeLayer*   frameLayer = [CAShapeLayer layer];
        frameLayer.frame = bounds;
        frameLayer.path = maskPath.CGPath;
        frameLayer.strokeColor = [UIColor redColor].CGColor;
        frameLayer.fillColor = nil;
    
        [self.layer addSublayer:frameLayer];
    }
    
    -(void)roundTopCornersRadius:(CGFloat)radius
    {
        [self roundCorners:(UIRectCornerTopLeft|UIRectCornerTopRight) radius:radius];
    }
    
    -(void)roundBottomCornersRadius:(CGFloat)radius
    {
        [self roundCorners:(UIRectCornerBottomLeft|UIRectCornerBottomRight) radius:radius];
    }
    

    The frame you're currently seeing drawn is the UITextField's normal frame, so set the frame style to none. You'll also have to adjust the insets to make up for the fact that with the frame style set to none there's normally no inset.

    0 讨论(0)
  • 2020-12-03 02:34

    Swift version of David Berry's answer:

    func roundCorners(corners:UIRectCorner, radius:CGFloat) {
        let bounds = self.bounds
    
        let maskPath = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSizeMake(radius, radius))
    
        let maskLayer = CAShapeLayer()
        maskLayer.frame = bounds
        maskLayer.path = maskPath.CGPath
    
        self.layer.mask = maskLayer
    
        let frameLayer = CAShapeLayer()
        frameLayer.frame = bounds
        frameLayer.path = maskPath.CGPath
        frameLayer.strokeColor = UIColor.redColor().CGColor
        frameLayer.fillColor = nil
    
        self.layer.addSublayer(frameLayer)
    }
    
    func roundTopCornersRadius(radius:CGFloat) {
        self.roundCorners([UIRectCorner.TopLeft, UIRectCorner.TopRight], radius:radius)
    }
    
    func roundBottomCornersRadius(radius:CGFloat) {
        self.roundCorners([UIRectCorner.BottomLeft, UIRectCorner.BottomRight], radius:radius)
    }
    
    0 讨论(0)
提交回复
热议问题