有没有办法为一个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;
以下是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
}
}
我不知道为什么你的解决方案没有工作,但下面的代码是为我工作。创建一个贝塞尔蒙版,并将其应用到您的视图。在下面的代码中,我将_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 2.0版本与一些改进:
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版本:
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
这里的快速扩展
注意,如果你有布局约束附加到它,你必须在你的UIView子类中按如下方式刷新它:
override func layoutSubviews() {
super.layoutSubviews()
roundCorners(corners: [.topLeft, .topRight], radius: 3.0)
}
如果你不这样做,它就不会出现。
和圆角,使用扩展:
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
}
}
附加的视图控制器情况:无论你不能或不想子类化一个视图,你仍然可以舍入一个视图。通过覆盖viewWillLayoutSubviews()函数,从它的视图控制器中完成,如下所示:
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)
}
}
一个可爱的扩展重用尤努斯Nedim Mehel解决方案
斯威夫特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
} }
使用
let view = UIView()
view.roundCornersWithLayerMask(10,[.TopLeft,.TopRight])
在Swift 4.2中,通过@IBDesignable创建它,如下所示:
@IBDesignable
class DesignableViewCustomCorner: UIView {
@IBInspectable var cornerRadious: CGFloat = 0 {
didSet {
let path = UIBezierPath(roundedRect: self.bounds, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: cornerRadious, height: cornerRadious))
let mask = CAShapeLayer()
mask.path = path.cgPath
self.layer.mask = mask
}
}
}