How to set cornerRadius for only top-left and top-right corner of a UIView?

后端 未结 26 2958
佛祖请我去吃肉
佛祖请我去吃肉 2020-11-22 06:14

Is there a way to set cornerRadius for only top-left and top-right corner of a UIView?

I tried the following, but it end up not seeing the

相关标签:
26条回答
  • 2020-11-22 06:48

    In Swift 4.2, Create it via @IBDesignable like this:

    @IBDesignable
    
    class DesignableViewCustomCorner: UIView {
    
        @IBInspectable var cornerRadious: CGFloat = 0 {
            didSet {
                let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: cornerRadious, height: cornerRadious))
                let mask = CAShapeLayer()
                mask.path = path.cgPath
                self.layer.mask = mask
            }
        }
    
    }
    
    0 讨论(0)
  • If you're looking for an interface builder only solution there is one for iOS 11 and higher. See my answer here: https://stackoverflow.com/a/58626264

    0 讨论(0)
  • 2020-11-22 06:50

    Swift 4

    extension UIView {
    
        func roundTop(radius:CGFloat = 5){
            self.clipsToBounds = true
            self.layer.cornerRadius = radius
            if #available(iOS 11.0, *) {
                self.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner]
            } else {
                // Fallback on earlier versions
            }
        }
    
        func roundBottom(radius:CGFloat = 5){
            self.clipsToBounds = true
            self.layer.cornerRadius = radius
            if #available(iOS 11.0, *) {
                self.layer.maskedCorners = [.layerMaxXMaxYCorner, .layerMinXMaxYCorner]
            } else {
                // Fallback on earlier versions
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-22 06:50

    Simple extension

    extension UIView {
        func roundCorners(corners: UIRectCorner, radius: CGFloat) {
            if #available(iOS 11, *) {
                self.clipsToBounds = true
                self.layer.cornerRadius = radius
                var masked = CACornerMask()
                if corners.contains(.topLeft) { masked.insert(.layerMinXMinYCorner) }
                if corners.contains(.topRight) { masked.insert(.layerMaxXMinYCorner) }
                if corners.contains(.bottomLeft) { masked.insert(.layerMinXMaxYCorner) }
                if corners.contains(.bottomRight) { masked.insert(.layerMaxXMaxYCorner) }
                self.layer.maskedCorners = masked
            }
            else {
                let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
                let mask = CAShapeLayer()
                mask.path = path.cgPath
                layer.mask = mask
            }
        }
    }
    

    Usage:

    view.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 12)
    
    0 讨论(0)
  • 2020-11-22 06:50

    For SwiftUI

    I found these solutions you can check from here https://stackoverflow.com/a/56763282/3716103

    I highly recommend the first one

    Option 1: Using Path + GeometryReader

    (more info on GeometryReader: https://swiftui-lab.com/geometryreader-to-the-rescue/)

    struct ContentView : View {
        var body: some View {
    
            Text("Hello World!")
                .foregroundColor(.white)
                .font(.largeTitle)
                .padding(20)
                .background(RoundedCorners(color: .blue, tl: 0, tr: 30, bl: 30, br: 0))
        }
    }
    

    RoundedCorners

    struct RoundedCorners: View {
    
        var color: Color = .white
    
        var tl: CGFloat = 0.0
        var tr: CGFloat = 0.0
        var bl: CGFloat = 0.0
        var br: CGFloat = 0.0
    
        var body: some View {
            GeometryReader { geometry in
                Path { path in
    
                    let w = geometry.size.width
                    let h = geometry.size.height
    
                    // Make sure we do not exceed the size of the rectangle
                    let tr = min(min(self.tr, h/2), w/2)
                    let tl = min(min(self.tl, h/2), w/2)
                    let bl = min(min(self.bl, h/2), w/2)
                    let br = min(min(self.br, h/2), w/2)
    
                    path.move(to: CGPoint(x: w / 2.0, y: 0))
                    path.addLine(to: CGPoint(x: w - tr, y: 0))
                    path.addArc(center: CGPoint(x: w - tr, y: tr), radius: tr, startAngle: Angle(degrees: -90), endAngle: Angle(degrees: 0), clockwise: false)
                    path.addLine(to: CGPoint(x: w, y: h - be))
                    path.addArc(center: CGPoint(x: w - br, y: h - br), radius: br, startAngle: Angle(degrees: 0), endAngle: Angle(degrees: 90), clockwise: false)
                    path.addLine(to: CGPoint(x: bl, y: h))
                    path.addArc(center: CGPoint(x: bl, y: h - bl), radius: bl, startAngle: Angle(degrees: 90), endAngle: Angle(degrees: 180), clockwise: false)
                    path.addLine(to: CGPoint(x: 0, y: tl))
                    path.addArc(center: CGPoint(x: tl, y: tl), radius: tl, startAngle: Angle(degrees: 180), endAngle: Angle(degrees: 270), clockwise: false)
                }
                .fill(self.color)
            }
        }
    }
    

    RoundedCorners_Previews

    struct RoundedCorners_Previews: PreviewProvider {
        static var previews: some View {
            RoundedCorners(color: .pink, tl: 40, tr: 40, bl: 40, br: 40)
        }
    }
    

    0 讨论(0)
  • 2020-11-22 06:51

    Swift 4 Swift 5 easy way in 1 line

    Usage:

    //MARK:- Corner Radius of only two side of UIViews
    self.roundCorners(view: yourview, corners: [.bottomLeft, .topRight], radius: 12.0)
    

    Function:

    //MARK:- Corner Radius of only two side of UIViews
    func roundCorners(view :UIView, corners: UIRectCorner, radius: CGFloat){
            let path = UIBezierPath(roundedRect: view.bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
            let mask = CAShapeLayer()
            mask.path = path.cgPath
            view.layer.mask = mask
    }
    

    In Objective-C

    Usage:

    [self.verticalSeparatorView roundCorners:UIRectCornerTopLeft radius:10.0];

    Function used in a Category (only one corner):

    -(void)roundCorners: (UIRectCorner) corners radius:(CGFloat)radius {
            UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(radius, radius)];
            CAShapeLayer *mask = [[CAShapeLayer alloc] init];
            mask.path = path.CGPath;
            self.layer.mask = mask;
        }
    
    0 讨论(0)
提交回复
热议问题