【问题标题】:How can you make a UIView with rounded top corners and square bottom corners如何制作具有圆角顶角和方形底角的 UIView
【发布时间】:2026-02-11 06:00:02
【问题描述】:

我正在尝试获得具有圆角顶角和方形底角的视图,类似于分组 UITableViewCell 的顶行。

有人知道一种不使用背景图像的简单绘制方法吗?

【问题讨论】:

标签: ios cocoa-touch uikit


【解决方案1】:

我不久前读过这篇文章:

Just two rounded corners?

还有这篇后续文章:

Round two corners in UIView

我认为这些应该回答你的问题。

【讨论】:

  • 考虑改进您的帖子,因为您的答案本质上是两个链接。请参阅:Are answers that just contain links elsewhere really “good answers”?Why is linking bad?
  • @Bavarious:如果不复制答案(主要是代码),我不确定在这种情况下如何做到这一点。即便如此,答案和第二篇文章的 cmets 包含许多相关细节。我会再看一遍,看看是否可以添加更多上下文。我感谢建设性的批评。
【解决方案2】:

Swift 4:适用于 iOS 11 及更高版本

override func viewDidLoad() {
    super.viewDidLoad()

    if #available(iOS 11.0, *) {
        self.viewToRound.clipsToBounds = true
        viewToRound.layer.cornerRadius = 20
        viewToRound.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
    } else {
        // Fallback on earlier versions
    }
}

早期 iOS 版本

override func viewDidLayoutSubviews() {
    self.viewToRound.clipsToBounds = true
    let path = UIBezierPath(roundedRect: viewToRound.bounds,
                            byRoundingCorners: [.topRight, .topLeft],
                            cornerRadii: CGSize(width: 20, height: 20))

    let maskLayer = CAShapeLayer()

    maskLayer.path = path.cgPath
    viewToRound.layer.mask = maskLayer
}

【讨论】:

    【解决方案3】:

    iOS 11 引入了一个名为CACornerMask 的新结构。

    使用这种结构,您可以对角进行更改:左上、右上、左下、右下。

    Swift 示例

    myView.clipsToBounds = true
    myView.layer.cornerRadius = 10
    myView.layer.maskedCorners = [.layerMinXMinYCorner,.layerMaxXMinYCorner]
    

    Objective-C 示例

    self.view.clipsToBounds = YES;
    self.view.layer.cornerRadius = 10;
    self.view.layer.maskedCorners = kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner;
    

    【讨论】:

      【解决方案4】:

      目标 C

      iOS 11 使用视图角半径

      if (@available(iOS 11.0, *)) {
                  _parentView.clipsToBounds = YES;
                  _parentView.layer.cornerRadius = 20;
                  _parentView.layer.maskedCorners = kCALayerMinXMinYCorner | kCALayerMaxXMinYCorner;
              } else {
                  UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:_parentView.bounds byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight) cornerRadii:CGSizeMake(20.0, 20.0)];
      
                  CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
                  maskLayer.frame = _parentView.bounds;
                  maskLayer.path  = maskPath.CGPath;
                  _parentView.layer.mask = maskLayer;
              }
      

      【讨论】: