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

后端 未结 26 2959
佛祖请我去吃肉
佛祖请我去吃肉 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:52

    Pay attention to the fact that if you have layout constraints attached to it, you must refresh this as follows in your UIView subclass:

    override func layoutSubviews() {
        super.layoutSubviews()
        roundCorners(corners: [.topLeft, .topRight], radius: 3.0)
    }
    

    If you don't do that it won't show up.


    And to round corners, use the extension:

    extension UIView {
       func roundCorners(corners: UIRectCorner, radius: CGFloat) {
            let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
            let mask = CAShapeLayer()
            mask.path = path.cgPath
            layer.mask = mask
        }
    }
    


    Additional view controller case: Whether you can't or wouldn't want to subclass a view, you can still round a view. Do it from its view controller by overriding the viewWillLayoutSubviews() function, as follows:

    class MyVC: UIViewController {
        /// The view to round the top-left and top-right hand corners
        let theView: UIView = {
            let v = UIView(frame: CGRect(x: 10, y: 10, width: 200, height: 200))
            v.backgroundColor = .red
            return v
        }()
    
        override func loadView() {
            super.loadView()
            view.addSubview(theView)
        }
    
        override func viewWillLayoutSubviews() {
            super.viewWillLayoutSubviews()
    
            // Call the roundCorners() func right there.
            theView.roundCorners(corners: [.topLeft, .topRight], radius: 30)
        }
    }
    
    0 讨论(0)
  • 2020-11-22 06:52

    Here is a short method implemented like this:

    - (void)viewDidLoad {
        [super viewDidLoad];
        UIButton *openInMaps = [UIButton new];
        [openInMaps setFrame:CGRectMake(15, 135, 114, 70)];
        openInMaps = (UIButton *)[self roundCornersOnView:openInMaps onTopLeft:NO topRight:NO bottomLeft:YES bottomRight:NO radius:5.0];
    }
    
    - (UIView *)roundCornersOnView:(UIView *)view onTopLeft:(BOOL)tl topRight:(BOOL)tr bottomLeft:(BOOL)bl bottomRight:(BOOL)br radius:(float)radius {
    
        if (tl || tr || bl || br) {
            UIRectCorner corner = 0;
            if (tl) {corner = corner | UIRectCornerTopLeft;}
            if (tr) {corner = corner | UIRectCornerTopRight;}
            if (bl) {corner = corner | UIRectCornerBottomLeft;}
            if (br) {corner = corner | UIRectCornerBottomRight;}
    
            UIView *roundedView = view;
            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;
        }
        return view;
    }
    
    0 讨论(0)
  • 2020-11-22 06:58

    And finally… there is CACornerMask in iOS11! With CACornerMask it can be done pretty easy:

    let view = UIView()
    view.clipsToBounds = true
    view.layer.cornerRadius = 10
    view.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner] // Top right corner, Top left corner respectively
    
    0 讨论(0)
  • 2020-11-22 06:58

    A lovely extension to reuse Yunus Nedim Mehel solution

    Swift 2.3

    extension UIView {
    func roundCornersWithLayerMask(cornerRadii: CGFloat, corners: UIRectCorner) {
        let path = UIBezierPath(roundedRect: bounds,
                                byRoundingCorners: corners,
                                cornerRadii: CGSize(width: cornerRadii, height: cornerRadii))
        let maskLayer = CAShapeLayer()
        maskLayer.path = path.CGPath
        layer.mask = maskLayer
    } }
    

    Usage

    let view = UIView()
    view.roundCornersWithLayerMask(10,[.TopLeft,.TopRight])
    
    0 讨论(0)
  • 2020-11-22 06:58

    After change bit of code @apinho In swift 4.3 working fine

    extension UIView {
    func roundCornersWithLayerMask(cornerRadii: CGFloat, corners: UIRectCorner) {
        let path = UIBezierPath(roundedRect: bounds,
                                byRoundingCorners: corners,
                                cornerRadii: CGSize(width: cornerRadii, height: cornerRadii))
        let maskLayer = CAShapeLayer()
        maskLayer.path = path.cgPath
        layer.mask = maskLayer
      }
    }
    

    To use this function for you view

    YourViewName. roundCornersWithLayerMask(cornerRadii: 20,corners: [.topLeft,.topRight])
    
    0 讨论(0)
  • 2020-11-22 06:59

    I am not sure why your solution did not work but the following code is working for me. Create a bezier mask and apply it to your view. In my code below I was rounding the bottom corners of the _backgroundView with a radius of 3 pixels. self is a custom UITableViewCell:

    UIBezierPath *maskPath = [UIBezierPath
        bezierPathWithRoundedRect:self.backgroundImageView.bounds
        byRoundingCorners:(UIRectCornerBottomLeft | UIRectCornerBottomRight)
        cornerRadii:CGSizeMake(20, 20)
    ];
    
    CAShapeLayer *maskLayer = [CAShapeLayer layer];
    
    maskLayer.frame = self.bounds;
    maskLayer.path = maskPath.CGPath;
    
    self.backgroundImageView.layer.mask = maskLayer;
    

    Swift version with some improvements:

    let path = UIBezierPath(roundedRect:viewToRound.bounds, byRoundingCorners:[.TopRight, .BottomLeft], cornerRadii: CGSizeMake(20, 20))
    let maskLayer = CAShapeLayer()
    
    maskLayer.path = path.CGPath
    viewToRound.layer.mask = maskLayer
    

    Swift 3.0 version:

    let path = UIBezierPath(roundedRect:viewToRound.bounds,
                            byRoundingCorners:[.topRight, .bottomLeft],
                            cornerRadii: CGSize(width: 20, height:  20))
    
    let maskLayer = CAShapeLayer()
    
    maskLayer.path = path.cgPath
    viewToRound.layer.mask = maskLayer
    

    Swift extension here

    0 讨论(0)
提交回复
热议问题