ios 如何仅为 UIView 的左上角和右上角设置cornerRadius?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10167266/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:52:49  来源:igfitidea点击:

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

ioscocoa-touchuiviewcornerradius

提问by tom

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

有没有办法cornerRadius只设置 a的左上角和右上角UIView

I tried the following, but it end up not seeing the view anymore.

我尝试了以下操作,但最终看不到视图。

UIView *view = [[UIView alloc] initWithFrame:frame];

CALayer *layer = [CALayer layer];
UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRoundedRect:frame byRoundingCorners:(UIRectCornerTopLeft|UIRectCornerTopRight) cornerRadii:CGSizeMake(3.0, 3.0)];
layer.shadowPath = shadowPath.CGPath;
view.layer.mask = layer;

采纳答案by Stéphane de Luca

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

请注意,如果您附加了布局约束,则必须在 UIView 子类中按如下方式刷新它:

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
    }
}

回答by Yunus Nedim Mehel

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 _backgroundViewwith a radius of 3 pixels. selfis a custom UITableViewCell:

我不确定为什么您的解决方案不起作用,但以下代码对我有用。创建一个贝塞尔蒙版并将其应用于您的视图。在我下面的代码中,我_backgroundView以 3 像素的半径将 的底角四舍五入。self是一个自定义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:

Swift 版本有一些改进:

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:

斯威夫特 3.0 版本:

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

Swift 扩展在这里

回答by Arbitur

Here is a Swiftversion of @JohnnyRockex answer

这是@JohnnyRockex 答案的Swift版本

extension UIView {

    func roundCorners(_ corners: UIRectCorner, radius: CGFloat) {
         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
    }

}


view.roundCorners([.topLeft, .bottomRight], radius: 10)

Note

笔记

If you're using Auto Layout, you'll need to subclass your UIViewand call roundCornersin the view's layoutSubviewsfor optimal effect.

如果您正在使用Auto Layout,则需要对视图进行子类化UIView并调用roundCornerslayoutSubviews获得最佳效果。

class View: UIView {
    override func layoutSubviews() {
        super.layoutSubviews()

        self.roundCorners([.topLeft, .bottomLeft], radius: 10)
    }
}

回答by Sergey Belous

And finally… there is CACornerMaskin iOS11! With CACornerMaskit can be done pretty easy:

最后……在iOS11中有 CACornerMask!有了CACornerMask它可以很容易地完成:

let view = UIView()
view.clipsToBounds = true
view.layer.cornerRadius = 10
view.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner] // Top right corner, Top left corner respectively

回答by Kurt Revis

Swift code example here: https://stackoverflow.com/a/35621736/308315

这里的 Swift 代码示例:https: //stackoverflow.com/a/35621736/308315



Not directly. You will have to:

不直接。你不得不:

  1. Create a CAShapeLayer
  2. Set its pathto be a CGPathRefbased on view.boundsbut with only two rounded corners (probably by using +[UIBezierPath bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:])
  3. Set your view.layer.maskto be the CAShapeLayer
  1. 创建一个 CAShapeLayer
  2. 将其设置pathCGPathRef基于view.bounds但只有两个圆角(可能通过使用+[UIBezierPath bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:]
  3. 设置你的view.layer.maskCAShapeLayer

回答by Johnny Rockex

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;
}

回答by iOS

In swift 4.1 and Xcode 9.4.1

在 swift 4.1 和 Xcode 9.4.1 中

In iOS 11this single line is enough:

iOS 11 中,这一行就足够了:

detailsSubView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]//Set your view here

See the complete code:

查看完整代码:

//In viewDidLoad
if #available(iOS 11.0, *){
        detailsSubView.clipsToBounds = false
        detailsSubView.layer.cornerRadius = 10
        detailsSubView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
} else {
      //For lower versions
}

But for lower versions

但是对于低版本

let rectShape = CAShapeLayer()
    rectShape.bounds = detailsSubView.frame
    rectShape.position = detailsSubView.center
    rectShape.path = UIBezierPath(roundedRect: detailsSubView.bounds,    byRoundingCorners: [.topLeft , .topRight], cornerRadii: CGSize(width: 20, height: 20)).cgPath
    detailsSubView.layer.mask = rectShape

Complete code is.

完整的代码是。

if #available(iOS 11.0, *){
    detailsSubView.clipsToBounds = false
    detailsSubView.layer.cornerRadius = 10
    detailsSubView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
}else{
    let rectShape = CAShapeLayer()
    rectShape.bounds = detailsSubView.frame
    rectShape.position = detailsSubView.center
    rectShape.path = UIBezierPath(roundedRect: detailsSubView.bounds,    byRoundingCorners: [.topLeft , .topRight], cornerRadii: CGSize(width: 20, height: 20)).cgPath
    detailsSubView.layer.mask = rectShape
}

If you are using AutoResizing in storyboard write this code in viewDidLayoutSubviews().

如果您在故事板中使用 AutoResizing,请在viewDidLayoutSubviews() 中编写此代码。

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    if #available(iOS 11.0, *){
        detailsSubView.clipsToBounds = false
        detailsSubView.layer.cornerRadius = 10
        detailsSubView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
    }else{
        let rectShape = CAShapeLayer()
        rectShape.bounds = detailsSubView.frame
        rectShape.position = detailsSubView.center
        rectShape.path = UIBezierPath(roundedRect: detailsSubView.bounds,    byRoundingCorners: [.topLeft , .topRight], cornerRadii: CGSize(width: 20, height: 20)).cgPath
        detailsSubView.layer.mask = rectShape
    }
}

回答by reza_khalafi

iOS 11 , Swift 4
And you can try this code:

iOS 11 , Swift 4
你可以试试这个代码:

if #available(iOS 11.0, *) {
   element.clipsToBounds = true
   element.layer.cornerRadius = CORNER_RADIUS
   element.layer.maskedCorners = [.layerMaxXMaxYCorner]
} else {
   // Fallback on earlier versions
}

And you can using this in table view cell.

你可以在表格视图单元格中使用它。

回答by pierre23

This would be the simplest answer:

这将是最简单的答案:

yourView.layer.cornerRadius = 8
yourView.layer.masksToBounds = true
yourView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]

回答by pierre23

Try this code,

试试这个代码,

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

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

view.layer.mask = maskLayer;