我真的很感激,如果有人能告诉我为什么下面的代码没有给我内心的影子,或者给我一个会产生内在阴影的解决方案。
我需要在圆形UIView上创建一个内部阴影。我已经经历了很多答案,并找到了将其放在普通平方UIViews上的方法,但是没有找到适用于圆形视图的解决方案。相反,我发现下面显示的解决方案对我来说看起来不错,但是当我实现它们时不要创建所需的内部阴影。这是我的屏幕,它是外部蓝色和内部黄色视图之间的白色视图,我想将阴影添加到:
我已经将视图子类化了,这里是我的draw rect代码:
let innerShadow = CALayer()
// Shadow path (1pt ring around bounds)
let path = UIBezierPath(rect: innerShadow.bounds.insetBy(dx: -1, dy: -1))
let cutout = UIBezierPath(rect: innerShadow.bounds).reversing()
path.append(cutout)
innerShadow.shadowPath = path.cgPath
innerShadow.masksToBounds = true
// Shadow properties
innerShadow.shadowColor = UIColor.darkGray.cgColor
innerShadow.shadowOffset = CGSize(width: 0.0, height: 7.0)
innerShadow.shadowOpacity = 1
innerShadow.shadowRadius = 5
// Add
self.layer.addSublayer(innerShadow)
// Make view round
self.layer.cornerRadius = self.frame.size.width/2
self.layer.masksToBounds = true
非常感谢您对此的任何帮助。如果您有任何疑问,请告诉我。
刚刚发现了这个
从蓝色视图的中心掩盖一个圆圈
let maskLayer = CAShapeLayer()
// based on the image the ring is 1 / 6 its diameter
let radius = self.bounds.width * 1.0 / 6.0
let path = UIBezierPath(rect: self.bounds)
let holeCenter = CGPoint(x: center.x - (radius * 2), y: center.y - (radius * 2))
path.addArc(withCenter: holeCenter, radius: radius, startAngle: 0, endAngle: CGFloat(2 * Double.pi), clockwise: true)
maskLayer.path = path.cgPath
maskLayer.fillRule = kCAFillRuleEvenOdd
blueView.layer.mask = maskLayer
以上会给你一个蓝色的戒指。
接下来创建一个blackView作为我们的影子
var blackView = UIView()
将其框架设置为与蓝色视图相同。
blackView.frame = blueView.frame
blackView.clipToBounds = true
从blackView中剪出一个类似的洞
let maskLayer = CAShapeLayer()
// This is the most important part, the mask shadow allows some of the black view to bleed from under the blue view and give a shadow
maskLayer.shadowOffset = CGSize(width: shadowX, height: shadowY)
maskLayer.shadowRadius = shadowRadius
let radius = self.bounds.width * 2.0 / 6.0
let path = UIBezierPath(rect: self.bounds)
let holeCenter = CGPoint(x: center.x - (radius * 2), y: center.y - (radius * 2))
path.addArc(withCenter: holeCenter, radius: radius, startAngle: 0, endAngle: CGFloat(2 * Double.pi), clockwise: true)
maskLayer.path = path.cgPath
maskLayer.fillRule = kCAFillRuleEvenOdd
blackView.layer.mask = maskLayer
UIView
的drop-in子类受PaintCode app的启发。
class ShadowView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = UIColor.groupTableViewBackground
let lbl = UILabel(frame: .zero)
addSubview(lbl)
lbl.translatesAutoresizingMaskIntoConstraints = false
lbl.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
lbl.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
lbl.text = "Text Inside"
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func draw(_ rect: CGRect) {
super.draw(rect)
innerShadowOval(frame: rect)
}
func innerShadowOval(frame: CGRect) {
let context = UIGraphicsGetCurrentContext()!
context.saveGState()
// oval color
let color = UIColor.clear
// shadow setup
let shadow = NSShadow()
shadow.shadowColor = UIColor.black
shadow.shadowOffset = CGSize(width: 2, height: 0)
shadow.shadowBlurRadius = 3
// oval path
let ovalPath = UIBezierPath(ovalIn: frame)
color.setFill()
ovalPath.fill()
// oval inner shadow
context.saveGState()
context.clip(to: ovalPath.bounds)
context.setShadow(offset: CGSize.zero, blur: 0)
context.setAlpha((shadow.shadowColor as! UIColor).cgColor.alpha)
context.beginTransparencyLayer(auxiliaryInfo: nil)
let ovalOpaqueShadow = (shadow.shadowColor as! UIColor).withAlphaComponent(1)
context.setShadow(offset: CGSize(width: shadow.shadowOffset.width,
height: shadow.shadowOffset.height),
blur: shadow.shadowBlurRadius,
color: ovalOpaqueShadow.cgColor)
context.setBlendMode(.sourceOut)
context.beginTransparencyLayer(auxiliaryInfo: nil)
ovalOpaqueShadow.setFill()
ovalPath.fill()
context.endTransparencyLayer()
context.endTransparencyLayer()
context.restoreGState()
context.restoreGState()
}
}
这就是结果