在 swift 中创建一个只有两个圆角的矩形?
Create a rectangle with just two rounded corners in swift?
我需要在 swift 中创建一个只有两个圆角的矩形(Objective C 代码也可以)。
目前我的代码正在用
创建两个矩形
CGPathCreateWithRoundedRect(CGRectMake(0, 0, 30, 60), 5, 5, nil);
和
CGPathCreateWithRoundedRect(CGRectMake(0, 0, 30, 60), 0, 0, nil);
并合并它们(有两个直角和两个圆角)但我对代码不满意,我很确定应该有更好的方法来做到这一点。
我是 iOS 和图形开发以及 swift 的新手。
在 Swift 2.3 中,您可以通过
let maskPath = UIBezierPath(roundedRect: anyView.bounds,
byRoundingCorners: [.BottomLeft, .BottomRight],
cornerRadii: CGSize(width: 10.0, height: 10.0))
let shape = CAShapeLayer()
shape.path = maskPath.CGPath
view.layer.mask = shape
在Objective-C中你可以使用UIBezierPath
class方法
bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:
示例实现-
// set the corner radius to the specified corners of the passed container
- (void)setMaskTo:(UIView*)view byRoundingCorners:(UIRectCorner)corners
{
UIBezierPath *rounded = [UIBezierPath bezierPathWithRoundedRect:view.bounds
byRoundingCorners:corners
cornerRadii:CGSizeMake(10.0, 10.0)];
CAShapeLayer *shape = [[CAShapeLayer alloc] init];
[shape setPath:rounded.CGPath];
view.layer.mask = shape;
}
并将上述方法调用为-
[self setMaskTo:anyView byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight];
这是您在 Swift 2.0
中所做的
var maskPath = UIBezierPath(roundedRect: anyView.bounds,
byRoundingCorners: [.BottomLeft, .BottomRight],
cornerRadii: CGSize(width: 10.0, height: 10.0))
更新:请参阅下面的 Swift 4 / iOS 11,这要容易得多
这是一个快速 Swift 3 扩展,您可以使用它来进行舍入和可选边框。
注意:如果您正在使用自动布局,您可能需要在视图生命周期回调之一(例如 viewDidLayoutSubviews
或 layoutSubviews
中对视图进行约束后调用它。
import UIKit
extension UIView {
/**
Rounds the given set of corners to the specified radius
- parameter corners: Corners to round
- parameter radius: Radius to round to
*/
func round(corners: UIRectCorner, radius: CGFloat) {
_ = _round(corners: corners, radius: radius)
}
/**
Rounds the given set of corners to the specified radius with a border
- parameter corners: Corners to round
- parameter radius: Radius to round to
- parameter borderColor: The border color
- parameter borderWidth: The border width
*/
func round(corners: UIRectCorner, radius: CGFloat, borderColor: UIColor, borderWidth: CGFloat) {
let mask = _round(corners: corners, radius: radius)
addBorder(mask: mask, borderColor: borderColor, borderWidth: borderWidth)
}
/**
Fully rounds an autolayout view (e.g. one with no known frame) with the given diameter and border
- parameter diameter: The view's diameter
- parameter borderColor: The border color
- parameter borderWidth: The border width
*/
func fullyRound(diameter: CGFloat, borderColor: UIColor, borderWidth: CGFloat) {
layer.masksToBounds = true
layer.cornerRadius = diameter / 2
layer.borderWidth = borderWidth
layer.borderColor = borderColor.cgColor;
}
}
private extension UIView {
@discardableResult func _round(corners: UIRectCorner, radius: CGFloat) -> CAShapeLayer {
let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
return mask
}
func addBorder(mask: CAShapeLayer, borderColor: UIColor, borderWidth: CGFloat) {
let borderLayer = CAShapeLayer()
borderLayer.path = mask.path
borderLayer.fillColor = UIColor.clear.cgColor
borderLayer.strokeColor = borderColor.cgColor
borderLayer.lineWidth = borderWidth
borderLayer.frame = bounds
layer.addSublayer(borderLayer)
}
}
Objective-C iWasRobbed 的回答版本:
UIView+RoundCorners.h
#import <UIKit/UIKit.h>
@interface UIView (RoundCorners)
/**
Rounds the given set of corners to the specified radius
- parameter corners: Corners to round
- parameter radius: Radius to round to
*/
- (void)roundCorners:(UIRectCorner)corners radius:(CGFloat)radius;
/**
Rounds the given set of corners to the specified radius with a border
- parameter corners: Corners to round
- parameter radius: Radius to round to
- parameter borderColor: The border color
- parameter borderWidth: The border width
*/
- (void)roundCorners:(UIRectCorner)corners radius:(CGFloat)radius borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth;
/**
Fully rounds an autolayout view (e.g. one with no known frame) with the given diameter and border
- parameter diameter: The view's diameter
- parameter borderColor: The border color
- parameter borderWidth: The border width
*/
- (void)fullyRoundWithDiameter:(CGFloat)diameter borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth;
@end
UIView+RoundCorners.m
#import "UIView+RoundCorners.h"
@implementation UIView (RoundCorners)
- (void)roundCorners:(UIRectCorner)corners radius:(CGFloat)radius {
[self _roundCorners:corners radius:radius];
}
- (void)roundCorners:(UIRectCorner)corners radius:(CGFloat)radius borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth {
CAShapeLayer *mask = [self _roundCorners:corners radius:radius];
[self addBorderWithMask:mask borderColor:borderColor borderWidth:borderWidth];
}
- (void)fullyRoundWithDiameter:(CGFloat)diameter borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth {
self.layer.masksToBounds = YES;
self.layer.cornerRadius = diameter / 2;
self.layer.borderWidth = borderWidth;
self.layer.borderColor = borderColor.CGColor;
}
- (CAShapeLayer *)_roundCorners:(UIRectCorner)corners radius:(CGFloat)radius {
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(radius, radius)];
CAShapeLayer *mask = [CAShapeLayer layer];
mask.path = path.CGPath;
self.layer.mask = mask;
return mask;
}
- (void)addBorderWithMask:(CAShapeLayer *)mask borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth {
CAShapeLayer *borderLayer = [CAShapeLayer layer];
borderLayer.path = mask.path;
borderLayer.fillColor = UIColor.clearColor.CGColor;
borderLayer.strokeColor = borderColor.CGColor;
borderLayer.lineWidth = borderWidth;
borderLayer.frame = self.bounds;
[self.layer addSublayer:borderLayer];
}
@end
更新 iWasRobbed 的答案以使用 Swift 3.0 GM 版本:
import UIKit
extension UIView {
/**
Rounds the given set of corners to the specified radius
- parameter corners: Corners to round
- parameter radius: Radius to round to
*/
func round(corners: UIRectCorner, radius: CGFloat) {
_round(corners: corners, radius: radius)
}
/**
Rounds the given set of corners to the specified radius with a border
- parameter corners: Corners to round
- parameter radius: Radius to round to
- parameter borderColor: The border color
- parameter borderWidth: The border width
*/
func round(corners: UIRectCorner, radius: CGFloat, borderColor: UIColor, borderWidth: CGFloat) {
let mask = _round(corners: corners, radius: radius)
addBorder(mask: mask, borderColor: borderColor, borderWidth: borderWidth)
}
/**
Fully rounds an autolayout view (e.g. one with no known frame) with the given diameter and border
- parameter diameter: The view's diameter
- parameter borderColor: The border color
- parameter borderWidth: The border width
*/
func fullyRound(diameter: CGFloat, borderColor: UIColor, borderWidth: CGFloat) {
layer.masksToBounds = true
layer.cornerRadius = diameter / 2
layer.borderWidth = borderWidth
layer.borderColor = borderColor.cgColor;
}
}
private extension UIView {
@discardableResult func _round(corners: UIRectCorner, radius: CGFloat) -> CAShapeLayer {
let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
return mask
}
func addBorder(mask: CAShapeLayer, borderColor: UIColor, borderWidth: CGFloat) {
let borderLayer = CAShapeLayer()
borderLayer.path = mask.path
borderLayer.fillColor = UIColor.clear.cgColor
borderLayer.strokeColor = borderColor.cgColor
borderLayer.lineWidth = borderWidth
borderLayer.frame = bounds
layer.addSublayer(borderLayer)
}
}
基于 Sanjay 的出色回答,我为 Swift 2.3 编写了一个快速 CALayer 扩展,以防您需要多次执行此类 "only round some corners" 操作。
extension CALayer {
func roundCorners(corners: UIRectCorner, radius: CGFloat) {
let maskPath = UIBezierPath(roundedRect: bounds,
byRoundingCorners: corners,
cornerRadii: CGSize(width: radius, height: radius))
let shape = CAShapeLayer()
shape.path = maskPath.CGPath
mask = shape
}
}
用法:
myView.layer.roundCorners([.TopLeft, .TopRight], radius: myCornerRadius)
Swift 3.0(在此示例中,边界来自视图而不是图层。使用视图中的边界使此代码可以与 UITableViewCell 中的视图一起使用。):
func roundCorners(corners: UIRectCorner, radius: CGFloat, viewBounds: CGRect) {
let maskPath = UIBezierPath(roundedRect: viewBounds,
byRoundingCorners: corners,
cornerRadii: CGSize(width: radius, height: radius))
let shape = CAShapeLayer()
shape.path = maskPath.cgPath
mask = shape
}
用法:
myView.layer.roundCorners(corners: [.topLeft, .topRight], radius: myCornerRadius, viewBounds: bounds)
2021 年最新...
请注意,syntax/systems 自很久以前提出这个问题以来已经发生了很大变化!
import UIKit
@IBDesignable
class RoundedEnds: UIView {
override func layoutSubviews() {
super.layoutSubviews()
setup()
}
func setup() {
let r = self.bounds.size.height / 2
let path = UIBezierPath(roundedRect: self.bounds, cornerRadius:r)
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
}
}
仅针对某些角落,只需将 path
行代码更改为:
let path = UIBezierPath(
roundedRect: self.bounds,
byRoundingCorners: [.topLeft,.topRight],
cornerRadii: CGSize(width: r, height: r))
Swift 3 - 有用的 UIView
扩展,当您需要圆化某些视图的特定角时:
extension UIView {
func round(corners: UIRectCorner, radius: CGFloat) {
let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
}
}
然后像这样使用它:
someView.round(corners: [.topLeft, .topRight], radius: 5)
Swift 4:
let maskPath = UIBezierPath(
roundedRect: view.bounds,
byRoundingCorners: [.allCorners],
cornerRadii: CGSize(width: 10.0, height: 10.0)
)
let shape = CAShapeLayer()
shape.path = maskPath.cgPath
view.layer.mask = shape
Swift 4+, iOS 11+
如果您已经有一个名为 myView
的 UIView
引用为 IBOutlet
,请尝试在 ViewDidLoad()
或加载它的任何地方添加以下两行:
myView.layer.cornerRadius = 10
myView.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
您可以将数组 []
更改为 MinX
、MinY
、MaxX
和 MaxY
的任意组合 select想要的角落。上面的例子圆了底部的两个角。
这只是另一种方法,根据您的设计可能会更简单一些。
iOS 11+ Only | You can check iOS usage stats here
说明
因为 CACornerMask
rawValue 是一个 UInt
你知道 CACornerMask
rawValue 是每个 CACornerMask.Element
的总和原始值
更具体地说:
- 左上角 (
layerMinXMinYCorner
) = 1
- 右上角 (
layerMaxXMinYCorner
) = 2
- 左下角 (
layerMinXMaxYCorner
) = 4
- 右下角 (
layerMaxXMaxYCorner
) = 8
例如,如果您想要 左上角 和 右上角 角,您只需键入 CACornerMask(rawValue: 3)
.
示例
下面是UIView
的简单扩展
extension UIView {
enum Corner:Int {
case bottomRight = 0,
topRight,
bottomLeft,
topLeft
}
private func parseCorner(corner: Corner) -> CACornerMask.Element {
let corners: [CACornerMask.Element] = [.layerMaxXMaxYCorner, .layerMaxXMinYCorner, .layerMinXMaxYCorner, .layerMinXMinYCorner]
return corners[corner.rawValue]
}
private func createMask(corners: [Corner]) -> UInt {
return corners.reduce(0, { (a, b) -> UInt in
return a + parseCorner(corner: b).rawValue
})
}
func roundCorners(corners: [Corner], amount: CGFloat = 5) {
layer.cornerRadius = amount
let maskedCorners: CACornerMask = CACornerMask(rawValue: createMask(corners: corners))
layer.maskedCorners = maskedCorners
}
}
你可以像这样使用它:
let myRect = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 50))
myRect.roundCorners(corners: [.topRight, .topLeft])
一个简单的 hack 可能如下所示。在图像中获取如下示例的视图。 红色视图 会有圆角,黄色视图(在红色视图内部)会防止圆角变圆
现在为 Red View 编写下面的代码。
self.myView.layer.cornerRadius = 15
确保您没有将任何代码编写为 clipsToBounds = true 或 masksToBounds = true。
下图是结果
Yellow View 的位置将决定哪 2 个角不会变圆。希望这很容易实现。
总之,您可以像这样创建漂亮的扩展程序:
extension UIView {
func roundCorners(_ corners: UIRectCorner, radius: Double) {
let maskPath = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let shape = CAShapeLayer()
shape.path = maskPath.cgPath
layer.mask = shape
}
}
这样使用:
view.roundCorners([.topRight, .bottomRight], radius: 10)
这是所有角的值:
- .topLeft
- .topRight
- .bottomLeft
- .bottomRight
extension CACornerMask {
public static var leftBottom : CACornerMask { get { return .layerMinXMaxYCorner}}
public static var rightBottom : CACornerMask { get { return .layerMaxXMaxYCorner}}
public static var leftTop : CACornerMask { get { return .layerMaxXMinYCorner}}
public static var rightTop : CACornerMask { get { return .layerMinXMinYCorner}}
}
extension CALayer {
func roundCorners(_ mask:CACornerMask,corner:CGFloat) {
self.maskedCorners = mask
self.cornerRadius = corner
}
}
self.viewBack.layer.roundCorners([.leftBottom,.rightBottom], corner: 23)
view.layer.cornerRadius = 10.0
view.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMaxYCorner, .layerMinXMaxYCorner]
Best way to do it!
Swift 5: 用于左上角和右上角。
yourView.layer.cornerRadius = 12
yourView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
我需要在 swift 中创建一个只有两个圆角的矩形(Objective C 代码也可以)。
目前我的代码正在用
创建两个矩形CGPathCreateWithRoundedRect(CGRectMake(0, 0, 30, 60), 5, 5, nil);
和
CGPathCreateWithRoundedRect(CGRectMake(0, 0, 30, 60), 0, 0, nil);
并合并它们(有两个直角和两个圆角)但我对代码不满意,我很确定应该有更好的方法来做到这一点。
我是 iOS 和图形开发以及 swift 的新手。
在 Swift 2.3 中,您可以通过
let maskPath = UIBezierPath(roundedRect: anyView.bounds,
byRoundingCorners: [.BottomLeft, .BottomRight],
cornerRadii: CGSize(width: 10.0, height: 10.0))
let shape = CAShapeLayer()
shape.path = maskPath.CGPath
view.layer.mask = shape
在Objective-C中你可以使用UIBezierPath
class方法
bezierPathWithRoundedRect:byRoundingCorners:cornerRadii:
示例实现-
// set the corner radius to the specified corners of the passed container
- (void)setMaskTo:(UIView*)view byRoundingCorners:(UIRectCorner)corners
{
UIBezierPath *rounded = [UIBezierPath bezierPathWithRoundedRect:view.bounds
byRoundingCorners:corners
cornerRadii:CGSizeMake(10.0, 10.0)];
CAShapeLayer *shape = [[CAShapeLayer alloc] init];
[shape setPath:rounded.CGPath];
view.layer.mask = shape;
}
并将上述方法调用为-
[self setMaskTo:anyView byRoundingCorners:UIRectCornerBottomLeft | UIRectCornerBottomRight];
这是您在 Swift 2.0
中所做的var maskPath = UIBezierPath(roundedRect: anyView.bounds,
byRoundingCorners: [.BottomLeft, .BottomRight],
cornerRadii: CGSize(width: 10.0, height: 10.0))
更新:请参阅下面的
这是一个快速 Swift 3 扩展,您可以使用它来进行舍入和可选边框。
注意:如果您正在使用自动布局,您可能需要在视图生命周期回调之一(例如 viewDidLayoutSubviews
或 layoutSubviews
中对视图进行约束后调用它。
import UIKit
extension UIView {
/**
Rounds the given set of corners to the specified radius
- parameter corners: Corners to round
- parameter radius: Radius to round to
*/
func round(corners: UIRectCorner, radius: CGFloat) {
_ = _round(corners: corners, radius: radius)
}
/**
Rounds the given set of corners to the specified radius with a border
- parameter corners: Corners to round
- parameter radius: Radius to round to
- parameter borderColor: The border color
- parameter borderWidth: The border width
*/
func round(corners: UIRectCorner, radius: CGFloat, borderColor: UIColor, borderWidth: CGFloat) {
let mask = _round(corners: corners, radius: radius)
addBorder(mask: mask, borderColor: borderColor, borderWidth: borderWidth)
}
/**
Fully rounds an autolayout view (e.g. one with no known frame) with the given diameter and border
- parameter diameter: The view's diameter
- parameter borderColor: The border color
- parameter borderWidth: The border width
*/
func fullyRound(diameter: CGFloat, borderColor: UIColor, borderWidth: CGFloat) {
layer.masksToBounds = true
layer.cornerRadius = diameter / 2
layer.borderWidth = borderWidth
layer.borderColor = borderColor.cgColor;
}
}
private extension UIView {
@discardableResult func _round(corners: UIRectCorner, radius: CGFloat) -> CAShapeLayer {
let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
return mask
}
func addBorder(mask: CAShapeLayer, borderColor: UIColor, borderWidth: CGFloat) {
let borderLayer = CAShapeLayer()
borderLayer.path = mask.path
borderLayer.fillColor = UIColor.clear.cgColor
borderLayer.strokeColor = borderColor.cgColor
borderLayer.lineWidth = borderWidth
borderLayer.frame = bounds
layer.addSublayer(borderLayer)
}
}
Objective-C iWasRobbed 的回答版本:
UIView+RoundCorners.h
#import <UIKit/UIKit.h>
@interface UIView (RoundCorners)
/**
Rounds the given set of corners to the specified radius
- parameter corners: Corners to round
- parameter radius: Radius to round to
*/
- (void)roundCorners:(UIRectCorner)corners radius:(CGFloat)radius;
/**
Rounds the given set of corners to the specified radius with a border
- parameter corners: Corners to round
- parameter radius: Radius to round to
- parameter borderColor: The border color
- parameter borderWidth: The border width
*/
- (void)roundCorners:(UIRectCorner)corners radius:(CGFloat)radius borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth;
/**
Fully rounds an autolayout view (e.g. one with no known frame) with the given diameter and border
- parameter diameter: The view's diameter
- parameter borderColor: The border color
- parameter borderWidth: The border width
*/
- (void)fullyRoundWithDiameter:(CGFloat)diameter borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth;
@end
UIView+RoundCorners.m
#import "UIView+RoundCorners.h"
@implementation UIView (RoundCorners)
- (void)roundCorners:(UIRectCorner)corners radius:(CGFloat)radius {
[self _roundCorners:corners radius:radius];
}
- (void)roundCorners:(UIRectCorner)corners radius:(CGFloat)radius borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth {
CAShapeLayer *mask = [self _roundCorners:corners radius:radius];
[self addBorderWithMask:mask borderColor:borderColor borderWidth:borderWidth];
}
- (void)fullyRoundWithDiameter:(CGFloat)diameter borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth {
self.layer.masksToBounds = YES;
self.layer.cornerRadius = diameter / 2;
self.layer.borderWidth = borderWidth;
self.layer.borderColor = borderColor.CGColor;
}
- (CAShapeLayer *)_roundCorners:(UIRectCorner)corners radius:(CGFloat)radius {
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:self.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(radius, radius)];
CAShapeLayer *mask = [CAShapeLayer layer];
mask.path = path.CGPath;
self.layer.mask = mask;
return mask;
}
- (void)addBorderWithMask:(CAShapeLayer *)mask borderColor:(UIColor *)borderColor borderWidth:(CGFloat)borderWidth {
CAShapeLayer *borderLayer = [CAShapeLayer layer];
borderLayer.path = mask.path;
borderLayer.fillColor = UIColor.clearColor.CGColor;
borderLayer.strokeColor = borderColor.CGColor;
borderLayer.lineWidth = borderWidth;
borderLayer.frame = self.bounds;
[self.layer addSublayer:borderLayer];
}
@end
更新 iWasRobbed 的答案以使用 Swift 3.0 GM 版本:
import UIKit
extension UIView {
/**
Rounds the given set of corners to the specified radius
- parameter corners: Corners to round
- parameter radius: Radius to round to
*/
func round(corners: UIRectCorner, radius: CGFloat) {
_round(corners: corners, radius: radius)
}
/**
Rounds the given set of corners to the specified radius with a border
- parameter corners: Corners to round
- parameter radius: Radius to round to
- parameter borderColor: The border color
- parameter borderWidth: The border width
*/
func round(corners: UIRectCorner, radius: CGFloat, borderColor: UIColor, borderWidth: CGFloat) {
let mask = _round(corners: corners, radius: radius)
addBorder(mask: mask, borderColor: borderColor, borderWidth: borderWidth)
}
/**
Fully rounds an autolayout view (e.g. one with no known frame) with the given diameter and border
- parameter diameter: The view's diameter
- parameter borderColor: The border color
- parameter borderWidth: The border width
*/
func fullyRound(diameter: CGFloat, borderColor: UIColor, borderWidth: CGFloat) {
layer.masksToBounds = true
layer.cornerRadius = diameter / 2
layer.borderWidth = borderWidth
layer.borderColor = borderColor.cgColor;
}
}
private extension UIView {
@discardableResult func _round(corners: UIRectCorner, radius: CGFloat) -> CAShapeLayer {
let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
return mask
}
func addBorder(mask: CAShapeLayer, borderColor: UIColor, borderWidth: CGFloat) {
let borderLayer = CAShapeLayer()
borderLayer.path = mask.path
borderLayer.fillColor = UIColor.clear.cgColor
borderLayer.strokeColor = borderColor.cgColor
borderLayer.lineWidth = borderWidth
borderLayer.frame = bounds
layer.addSublayer(borderLayer)
}
}
基于 Sanjay 的出色回答,我为 Swift 2.3 编写了一个快速 CALayer 扩展,以防您需要多次执行此类 "only round some corners" 操作。
extension CALayer {
func roundCorners(corners: UIRectCorner, radius: CGFloat) {
let maskPath = UIBezierPath(roundedRect: bounds,
byRoundingCorners: corners,
cornerRadii: CGSize(width: radius, height: radius))
let shape = CAShapeLayer()
shape.path = maskPath.CGPath
mask = shape
}
}
用法:
myView.layer.roundCorners([.TopLeft, .TopRight], radius: myCornerRadius)
Swift 3.0(在此示例中,边界来自视图而不是图层。使用视图中的边界使此代码可以与 UITableViewCell 中的视图一起使用。):
func roundCorners(corners: UIRectCorner, radius: CGFloat, viewBounds: CGRect) {
let maskPath = UIBezierPath(roundedRect: viewBounds,
byRoundingCorners: corners,
cornerRadii: CGSize(width: radius, height: radius))
let shape = CAShapeLayer()
shape.path = maskPath.cgPath
mask = shape
}
用法:
myView.layer.roundCorners(corners: [.topLeft, .topRight], radius: myCornerRadius, viewBounds: bounds)
2021 年最新...
请注意,syntax/systems 自很久以前提出这个问题以来已经发生了很大变化!
import UIKit
@IBDesignable
class RoundedEnds: UIView {
override func layoutSubviews() {
super.layoutSubviews()
setup()
}
func setup() {
let r = self.bounds.size.height / 2
let path = UIBezierPath(roundedRect: self.bounds, cornerRadius:r)
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
}
}
仅针对某些角落,只需将 path
行代码更改为:
let path = UIBezierPath(
roundedRect: self.bounds,
byRoundingCorners: [.topLeft,.topRight],
cornerRadii: CGSize(width: r, height: r))
Swift 3 - 有用的 UIView
扩展,当您需要圆化某些视图的特定角时:
extension UIView {
func round(corners: UIRectCorner, radius: CGFloat) {
let path = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
}
}
然后像这样使用它:
someView.round(corners: [.topLeft, .topRight], radius: 5)
Swift 4:
let maskPath = UIBezierPath(
roundedRect: view.bounds,
byRoundingCorners: [.allCorners],
cornerRadii: CGSize(width: 10.0, height: 10.0)
)
let shape = CAShapeLayer()
shape.path = maskPath.cgPath
view.layer.mask = shape
Swift 4+, iOS 11+
如果您已经有一个名为 myView
的 UIView
引用为 IBOutlet
,请尝试在 ViewDidLoad()
或加载它的任何地方添加以下两行:
myView.layer.cornerRadius = 10
myView.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
您可以将数组 []
更改为 MinX
、MinY
、MaxX
和 MaxY
的任意组合 select想要的角落。上面的例子圆了底部的两个角。
这只是另一种方法,根据您的设计可能会更简单一些。
iOS 11+ Only | You can check iOS usage stats here
说明
因为 CACornerMask
rawValue 是一个 UInt
你知道 CACornerMask
rawValue 是每个 CACornerMask.Element
的总和原始值
更具体地说:
- 左上角 (
layerMinXMinYCorner
) = 1 - 右上角 (
layerMaxXMinYCorner
) = 2 - 左下角 (
layerMinXMaxYCorner
) = 4 - 右下角 (
layerMaxXMaxYCorner
) = 8
例如,如果您想要 左上角 和 右上角 角,您只需键入 CACornerMask(rawValue: 3)
.
示例
下面是UIView
extension UIView {
enum Corner:Int {
case bottomRight = 0,
topRight,
bottomLeft,
topLeft
}
private func parseCorner(corner: Corner) -> CACornerMask.Element {
let corners: [CACornerMask.Element] = [.layerMaxXMaxYCorner, .layerMaxXMinYCorner, .layerMinXMaxYCorner, .layerMinXMinYCorner]
return corners[corner.rawValue]
}
private func createMask(corners: [Corner]) -> UInt {
return corners.reduce(0, { (a, b) -> UInt in
return a + parseCorner(corner: b).rawValue
})
}
func roundCorners(corners: [Corner], amount: CGFloat = 5) {
layer.cornerRadius = amount
let maskedCorners: CACornerMask = CACornerMask(rawValue: createMask(corners: corners))
layer.maskedCorners = maskedCorners
}
}
你可以像这样使用它:
let myRect = UIView(frame: CGRect(x: 0, y: 0, width: 200, height: 50))
myRect.roundCorners(corners: [.topRight, .topLeft])
一个简单的 hack 可能如下所示。在图像中获取如下示例的视图。 红色视图 会有圆角,黄色视图(在红色视图内部)会防止圆角变圆
现在为 Red View 编写下面的代码。
self.myView.layer.cornerRadius = 15
确保您没有将任何代码编写为 clipsToBounds = true 或 masksToBounds = true。
下图是结果
Yellow View 的位置将决定哪 2 个角不会变圆。希望这很容易实现。
总之,您可以像这样创建漂亮的扩展程序:
extension UIView {
func roundCorners(_ corners: UIRectCorner, radius: Double) {
let maskPath = UIBezierPath(roundedRect: bounds, byRoundingCorners: corners, cornerRadii: CGSize(width: radius, height: radius))
let shape = CAShapeLayer()
shape.path = maskPath.cgPath
layer.mask = shape
}
}
这样使用:
view.roundCorners([.topRight, .bottomRight], radius: 10)
这是所有角的值:
- .topLeft
- .topRight
- .bottomLeft
- .bottomRight
extension CACornerMask {
public static var leftBottom : CACornerMask { get { return .layerMinXMaxYCorner}}
public static var rightBottom : CACornerMask { get { return .layerMaxXMaxYCorner}}
public static var leftTop : CACornerMask { get { return .layerMaxXMinYCorner}}
public static var rightTop : CACornerMask { get { return .layerMinXMinYCorner}}
}
extension CALayer {
func roundCorners(_ mask:CACornerMask,corner:CGFloat) {
self.maskedCorners = mask
self.cornerRadius = corner
}
}
self.viewBack.layer.roundCorners([.leftBottom,.rightBottom], corner: 23)
view.layer.cornerRadius = 10.0
view.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMaxYCorner, .layerMinXMaxYCorner]
Best way to do it!
Swift 5: 用于左上角和右上角。
yourView.layer.cornerRadius = 12
yourView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]