阴影设置(矩形:)当视图重绘
问题描述:
问题移除:阴影设置(矩形:)当视图重绘
我已经实现具有弯曲底部边界上面我的滚动视图坐在一个梯度层的可折叠头视图。该头文件具有绘制在其绘制(rect :)函数中的投影。阴影给底部边框发光效果。一切看起来不错,但是当setNeedsDisplay()在我的标题上被调用或视图重绘时,投影会消失。
问:
我如何当视图重绘的阴影依然存在?
代码:
override func draw(_ rect: CGRect) {
super.draw(rect)
let p1 = CGPoint(x: 0, y: self.frame.height * 0.8)
let p2 = CGPoint(x: self.frame.width/2, y: self.frame.height * 1.06)
let p3 = CGPoint(x: self.frame.width, y: self.frame.height * 0.8)
let p4 = CGPoint(x: self.frame.width, y: 0)
let p5 = CGPoint(x: 0, y: 0)
let path = UIBezierPath()
path.move(to: p1)
path.addQuadCurve(to: p3, controlPoint: p2)
path.addLine(to: p4)
path.addLine(to: p5)
path.addLine(to: p1)
path.close()
self.shapeLayer.path = path.cgPath
self.layer.mask = self.shapeLayer
if !self.didSetGradient {
self.gradient = CustomColors.blueGreenBackgroundGradient(frame: path.bounds)
self.gradient.mask = shapeLayer
self.gradient.masksToBounds = true
self.gradient.removeFromSuperlayer()
self.layer.insertSublayer(self.gradient, at: 0)
self.didSetGradient = true
}
let context = UIGraphicsGetCurrentContext()
context?.saveGState()
context?.setShadow(offset: CGSize(width: 0, height: 2.5), blur: 15, color: CustomColors.green.cgColor)
CustomColors.blueGreen.setStroke()
UIColor.clear.setFill()
path.lineWidth = 5
path.stroke()
context?.restoreGState()
}
答
Aight能弄清楚这一个。当视图重绘时,贝塞尔路径阴影变得隐藏,因为图层蒙版被设置为shapeLayer。我的解决方案是使用图层的shadowPath
属性绘制曲线阴影,并将shapeLayer
作为子图层插入,而不是掩盖图层。请确保在添加渐变之前添加shapeLayer
,以便渐变显示在shapeLayer
的顶部。作为@dfd提到的didSetGradient
块非常俗气,但它现在正在工作!
override func draw(_ rect: CGRect) {
super.draw(rect)
let p1 = CGPoint(x: 0, y: self.frame.height * 0.8)
let p2 = CGPoint(x: self.frame.width/2, y: self.frame.height * 1.06)
let p3 = CGPoint(x: self.frame.width, y: self.frame.height * 0.8)
let p4 = CGPoint(x: self.frame.width, y: 0)
let p5 = CGPoint(x: 0, y: 0)
let path = UIBezierPath()
path.move(to: p1)
path.addQuadCurve(to: p3, controlPoint: p2)
path.addLine(to: p4)
path.addLine(to: p5)
path.addLine(to: p1)
path.close()
self.shapeLayer.path = path.cgPath
if !self.didSetGradient {
self.layer.insertSublayer(shapeLayer, at: 0)
self.gradient = CustomColors.blueGreenBackgroundGradient(frame: path.bounds)
self.gradient.mask = shapeLayer
self.gradient.masksToBounds = true
self.layer.insertSublayer(self.gradient, at: 0)
self.didSetGradient = true
}
self.layer.shadowPath = startPath.cgPath
self.layer.shadowColor = CustomColors.blueGreen.cgColor
self.layer.shadowOpacity = 0.5
self.layer.shadowRadius = 8
self.layer.shadowOffset = CGSize(width: 0, height: 7)
self.layer.masksToBounds = false
self.clipsToBounds = false
}
我不知道,如果你需要'setNeedsDisplay'等给出了答案,而是 - 你设置'绘制一个断点(RECT;)'?以下是我关心的内容:您的渐变位于“if!self.didSetGradient”内部,以及第二次*调用事件如何执行此操作?是否有某个地方?重置*'didSetGradient'? – dfd
@dfd我不需要'setNeedsDisplay',但是每当需要更新视图时都会调用'draw(rect:)'函数,那就是当我遇到问题时。我调用'setNeedsDisplay'来强制重绘视图来帮助调试。 'self.didSetGradient'是一个var类,当视图被实例化时被声明为false,所以渐变只被设置一次。如果没有这个条件,那么在重绘视图时第二次设置渐变时不能正确遮罩。对这个和阴影的建议将非常感谢! –
现在删除了一个答案,建议调用'setNeedsDisplay'。我正在引用这个。我同意'draw(rect :)是代码的正确位置。但是......一旦你将'didSetGradient'设置为true - 意味着* first *时间的事物被绘制 - 它是如何被设置为false的?除非将其设置为false *,然后重绘,否则不会重绘渐变。 – dfd