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

tom*_*tom 372 cocoa-touch cornerradius uiview ios

有没有办法cornerRadius只设置一个左上角和右上角UIView

我尝试了以下内容,但最终没有看到视图了.

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;
Run Code Online (Sandbox Code Playgroud)

Yun*_*hel 524

我不确定为什么你的解决方案不起作用,但以下代码对我有用.创建一个贝塞尔蒙版并将其应用于您的视图.在下面的代码中,我_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;
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

Swift 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
Run Code Online (Sandbox Code Playgroud)

Swift扩展到这里

  • @RainerLiao我有同样的问题,我在`viewDidLoad`方法做了所有这些,将它移到`viewDidAppear`并且它有效. (8认同)
  • 在文本字段中尝试。左成功,右失败 (2认同)

Arb*_*tur 256

这是@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
    }

}
Run Code Online (Sandbox Code Playgroud)
view.roundCorners([.topLeft, .bottomRight], radius: 10)
Run Code Online (Sandbox Code Playgroud)

注意

如果您正在使用自动布局,则需要对您进行子类化UIViewroundCorners在视图中调用以layoutSubviews获得最佳效果.

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

        self.roundCorners([.topLeft, .bottomLeft], radius: 10)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 伟大的延伸.但是:`.TopRight`和`.BottomRight`对我来说似乎不起作用. (9认同)
  • 如果你使用自动布局,并且没有对想要舍入的视图的引用,你可以调用`.layoutIfNeeded()`,然后这个方法. (9认同)
  • on*Swift 2*:`view.roundCorners([.TopLeft,.BottomLeft],radius:10)` (4认同)
  • @dosdos查看和在layoutSubviews中查看自己角落的子类. (3认同)
  • 它没有在Right上运行,因为你的视图界限还没有很好地定义自动布局...我目前面临同样的问题. (2认同)

Sté*_*uca 162

斯威夫特4

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

override func layoutSubviews() {
    super.layoutSubviews()
    roundCorners(corners: [.topLeft, .topRight], radius: 3.0)
}
Run Code Online (Sandbox Code Playgroud)

如果你不这样做,它就不会出现.


对于圆角,请使用扩展名:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 这绝对不是一个答案,作者问的是如何使特定的角变圆,而不是如何使角半径与布局更改同步。 (2认同)
  • 答案最近已修复.. @kelin (2认同)
  • 这绝对是拐角处。 (2认同)
  • 如果有人面临与我相同的虚拟问题 - 如果您在 ViewController 中编写,请不要忘记 override func viewDidLayoutSubviews() { roundCorners() } (2认同)

Ser*_*ous 150

最后......在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
Run Code Online (Sandbox Code Playgroud)

  • @Aliens和......我提到了. (13认同)
  • 这绝对是最好的。在圆化动态调整表格视图单元格的边缘时,我们总是遇到其他解决方案的问题。 (6认同)
  • 项目必须支持iOS 11以上才能使用该解决方案. (2认同)
  • 这应该是最重要的答案。这是对OP问题最直接、最相关的答案。 (2认同)
  • 让我们把它放在首位 (2认同)

Kur*_*vis 99

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


不是直接的.你不得不:

  1. 创建一个 CAShapeLayer
  2. 设置它pathCGPathRef基于view.bounds但只有两个圆角(可能通过使用+[UIBezierPath bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:])
  3. 把你view.layer.mask做成为CAShapeLayer

  • 请注意,如果你不仅仅是在几个观点上这样做,这将损害性能...... (21认同)

Joh*_*kex 63

这是一个像这样实现的简短方法:

- (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;
}
Run Code Online (Sandbox Code Playgroud)


pie*_*e23 31

这将是最简单的答案:

yourView.layer.cornerRadius = 8
yourView.layer.masksToBounds = true
yourView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
Run Code Online (Sandbox Code Playgroud)


Nei*_*tha 27

有一个超级简单的方法。我在这里找到

view.clipsToBounds = true
view.layer.cornerRadius = 24
view.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
Run Code Online (Sandbox Code Playgroud)

cornerRadiusCALayer视图的上使用 stock属性。你只需要定义角落。 layerMinXMinYCorner是左上角layerMaxXMinYCorner是右上角。


iOS*_*iOS 24

在swift 4.1和Xcode 9.4.1中

iOS 11中,这一行足够了:

detailsSubView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]//Set your view here
Run Code Online (Sandbox Code Playgroud)

查看完整代码:

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

但对于较低版本

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
Run Code Online (Sandbox Code Playgroud)

完整的代码是.

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
}
Run Code Online (Sandbox Code Playgroud)

如果您在storyboard中使用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
    }
}
Run Code Online (Sandbox Code Playgroud)


rez*_*afi 23

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
}
Run Code Online (Sandbox Code Playgroud)

您可以在表格视图单元格中使用它.

  • 这是今天编码的正确答案。再见遮罩层。 (2认同)

小智 16

试试这段代码,

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;
Run Code Online (Sandbox Code Playgroud)


Ban*_*e M 16

我在 swift 中舍入 UIView 和 UITextFiels 的特定角的解决方案是使用

.layer.cornerRadius

layer.maskedCorners

实际的 UIView 或 UITextFields。

例子:

fileprivate func inputTextFieldStyle() {
        inputTextField.layer.masksToBounds = true
        inputTextField.layer.borderWidth = 1
        inputTextField.layer.cornerRadius = 25
        inputTextField.layer.maskedCorners = [.layerMaxXMaxYCorner,.layerMaxXMinYCorner]
        inputTextField.layer.borderColor = UIColor.white.cgColor
    }
Run Code Online (Sandbox Code Playgroud)

并通过使用

.layerMaxXMaxYCorner

.layerMaxXMinYCorner

,我可以指定要四舍五入的 UITextField 的右上角和右下角。

你可以在这里看到结果:

在此处输入图片说明


Dav*_*rta 15

艾玛:.TopRight.BottomRight没有为你工作,也许是因为view.roundCorners在最终之前完成了对呼叫view bounds的计算.请注意,Bezier Path它是在调用时从视图边界派生的.例如,如果自动布局会缩小视图范围,则右侧的圆角可能位于视图外部.尝试调用它viewDidLayoutSubviews,视图的边界是最终的.


Sha*_*med 11

1行中的Swift 4 Swift 5简单方法

用法:

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

功能:

//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
}
Run Code Online (Sandbox Code Playgroud)

  • 只记得在 viewDidLayoutSubviews 完成之前不会计算视图的角,因此您应该在其中调用 roundCorners func (3认同)

Vip*_*mar 9

使用这个扩展,它将涵盖一切。

extension UIView {

   func roundTopCorners(radius: CGFloat = 10) {
    
       self.clipsToBounds = true
       self.layer.cornerRadius = radius
       if #available(iOS 11.0, *) {
           self.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
       } else {
           self.roundCorners(corners: [.topLeft, .topRight], radius: radius)
       }
   }

   func roundBottomCorners(radius: CGFloat = 10) {
    
       self.clipsToBounds = true
       self.layer.cornerRadius = radius
       if #available(iOS 11.0, *) {
           self.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
       } else {
           self.roundCorners(corners: [.bottomLeft, .bottomRight], radius: radius)
       }
   }

   private 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
    }
}
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它:-

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
            
    self.yourView.roundTopCorners()
}
Run Code Online (Sandbox Code Playgroud)

注意:- 我建议您不要将此代码放在viewDidLayoutSubviews()内,因为每当视图更新时,您都会在其中收到调用。所以使用viewDidAppear(),它会像一个魅力一样工作。


Fun*_*Kat 8

简单的扩展

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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

view.roundCorners(corners: [.bottomLeft, .bottomRight], radius: 12)
Run Code Online (Sandbox Code Playgroud)


MrM*_*ins 7

斯威夫特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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Dmy*_*huk 7

这是Swift 5 的最佳方法:

import UIKit

extension UIView {

func roundCorners(radius: CGFloat = 10, corners: UIRectCorner = .allCorners) {
        self.clipsToBounds = true
        self.layer.cornerRadius = radius
        if #available(iOS 11.0, *) {
            var arr: CACornerMask = []
            
            let allCorners: [UIRectCorner] = [.topLeft, .topRight, .bottomLeft, .bottomRight, .allCorners]
            
            for corn in allCorners {
                if(corners.contains(corn)){
                    switch corn {
                    case .topLeft:
                        arr.insert(.layerMinXMinYCorner)
                    case .topRight:
                        arr.insert(.layerMaxXMinYCorner)
                    case .bottomLeft:
                        arr.insert(.layerMinXMaxYCorner)
                    case .bottomRight:
                        arr.insert(.layerMaxXMaxYCorner)
                    case .allCorners:
                        arr.insert(.layerMinXMinYCorner)
                        arr.insert(.layerMaxXMinYCorner)
                        arr.insert(.layerMinXMaxYCorner)
                        arr.insert(.layerMaxXMaxYCorner)
                    default: break
                    }
                }
            }
            self.layer.maskedCorners = arr
        } else {
            self.roundCornersBezierPath(corners: corners, radius: radius)
        }
    }
    
    private func roundCornersBezierPath(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
    }
    
}
Run Code Online (Sandbox Code Playgroud)


Nat*_*mer 6

以编程方式执行此操作的方法是创建具有圆角UIView的顶部UIView.或者你可以隐藏在某些东西下方的顶部.

  • 这是一个非常难看的解决方案:P (6认同)
  • 为什么这会被贬低?这是一种快速有效的解决方案 (4认同)

Spy*_*ydy 6

    // Create the path (with only the top-left corner rounded)
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:view.bounds 
                           byRoundingCorners:(UIRectCornerBottomLeft | UIRectCornerBottomRight) 
                           cornerRadii:CGSizeMake(7.0, 7.0)];

// Create the shape layer and set its path
CAShapeLayer *maskLayer = [CAShapeLayer layer];
maskLayer.frame = cell.stripBlackImnageView.bounds;
maskLayer.path = maskPath.CGPath; 
// Set the newly created shapelayer as the mask for the image view's layer
view.layer.mask = maskLayer;
Run Code Online (Sandbox Code Playgroud)