使用 UIBezierPath 为带有阴影的选定边缘添加角半径 | iOS |斯威夫特 4.2
Posted
技术标签:
【中文标题】使用 UIBezierPath 为带有阴影的选定边缘添加角半径 | iOS |斯威夫特 4.2【英文标题】:Adding Corner radius for selected edges with shadow using UIBezierPath | iOS | Swift 4.2 【发布时间】:2019-07-12 15:04:22 【问题描述】:我正在尝试在我的视图上添加阴影。它有 3 个圆形边缘。实现这个 UIBezierPath 然后设置 CAShapelayer 用这个路径作为视图层上的掩码。现在,如果我试图在这个视图上添加阴影,它不会显示。我已经经历了一个类似的问题并提出了答案,但在我的情况下没有任何效果。以下是我的实现:
class BubbleView: UIView
override func draw(_ rect: CGRect)
super.draw(rect)
override func layoutSubviews()
super.layoutSubviews()
self.updateContainerLayer()
func updateContainerLayer()
let brazierPath: UIBezierPath = UIBezierPath(roundedRect: self.bounds,
byRoundingCorners: [.bottomRight, .bottomLeft, .topLeft],
cornerRadii: CGSize(width: 15.0, height: 0.0))
//1
let shapeLayer = CAShapeLayer()
shapeLayer.path = brazierPath.cgPath
self.layer.mask = shapeLayer
//2
self.layer.shadowColor = UIColor(r: 0, g: 0, b: 0, alpha: 0.25).cgColor
self.layer.shadowOpacity = 1.0
self.layer.shadowOffset = CGSize(width: 0.0, height: 0.5)
self.layer.shadowRadius = 1.5
self.layer.shadowPath = brazierPath.cgPath
//3
self.layer.masksToBounds = true
self.clipsToBounds = false
//4
self.layer.shouldRasterize = true
self.layer.rasterizationScale = UIScreen.main.scale
【问题讨论】:
【参考方案1】:如果您的目标是 iOS 11+,您可以使用图层的 .maskedCorners
属性:
class BubbleView: UIView
// don't override draw()
// override func draw(_ rect: CGRect)
// super.draw(rect)
//
override func layoutSubviews()
super.layoutSubviews()
self.updateContainerLayer()
func updateContainerLayer()
let brazierPath: UIBezierPath = UIBezierPath(roundedRect: self.bounds,
byRoundingCorners: [.bottomRight, .bottomLeft, .topLeft],
cornerRadii: CGSize(width: 15.0, height: 0.0))
//1
// let shapeLayer = CAShapeLayer()
// shapeLayer.path = brazierPath.cgPath
// self.layer.mask = shapeLayer
// ios 11+ use .maskedCorners
self.layer.cornerRadius = 15.0
self.layer.maskedCorners = [.layerMinXMinYCorner, .layerMinXMaxYCorner, .layerMaxXMaxYCorner]
//2
self.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.25).cgColor
self.layer.shadowOpacity = 1.0
self.layer.shadowOffset = CGSize(width: 0.0, height: 0.5)
self.layer.shadowRadius = 1.5
self.layer.shadowPath = brazierPath.cgPath
//3
self.layer.masksToBounds = true
self.clipsToBounds = false
//4
self.layer.shouldRasterize = true
self.layer.rasterizationScale = UIScreen.main.scale
结果:
结果带有夸张的.shadowOffset = CGSize(width: -10.0, height: 10.5)
以便于看到阴影:
如果您需要允许早期的 iOS 版本,我相信您需要使用容器视图方法。
编辑:
另一种方法,对阴影使用“容器”视图。这适用于早于 11 的 iOS...它使用相同的 UIBezierPath
作为“内容视图”掩码和阴影路径:
类 BubbleView: UIView
let contentView: UIView =
let v = UIView()
v.translatesAutoresizingMaskIntoConstraints = false
return v
()
override init(frame: CGRect)
super.init(frame: frame)
commonInit()
required init?(coder aDecoder: NSCoder)
super.init(coder: aDecoder)
commonInit()
func commonInit() -> Void
addSubview(contentView)
NSLayoutConstraint.activate([
contentView.topAnchor.constraint(equalTo: topAnchor),
contentView.bottomAnchor.constraint(equalTo: bottomAnchor),
contentView.leadingAnchor.constraint(equalTo: leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: trailingAnchor),
])
self.clipsToBounds = false
backgroundColor = .clear
contentView.backgroundColor = .red
// set non-changing properties here
contentView.layer.masksToBounds = true
self.layer.shadowColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.25).cgColor
self.layer.shadowOpacity = 1.0
self.layer.shadowOffset = CGSize(width: 0.0, height: 0.5)
// exaggerated shadow offset so we can see it easily
//self.layer.shadowOffset = CGSize(width: -10.0, height: 10.5)
self.layer.shadowRadius = 1.5
self.layer.shouldRasterize = true
self.layer.rasterizationScale = UIScreen.main.scale
override func layoutSubviews()
super.layoutSubviews()
let bezierPath = UIBezierPath(roundedRect: self.bounds,
byRoundingCorners: [.bottomRight, .bottomLeft, .topLeft],
cornerRadii: CGSize(width: 15.0, height: 0.0))
let shapeLayer = CAShapeLayer()
shapeLayer.path = bezierPath.cgPath
contentView.layer.mask = shapeLayer
self.layer.shadowPath = bezierPath.cgPath
与 11+ 示例一样,结果:
并且 Result 带有一个夸张的.shadowOffset = CGSize(width: -10.0, height: 10.5)
以便于看到阴影:
【讨论】:
感谢您的解决方案。但我也瞄准了 iOS 10。 “容器视图方法”。 - 你能详细说明一下吗? 谢谢!!稍加调整和您的建议,终于完成了!以上是关于使用 UIBezierPath 为带有阴影的选定边缘添加角半径 | iOS |斯威夫特 4.2的主要内容,如果未能解决你的问题,请参考以下文章