2017-08-01 41 views
1

問題移除:陰影設置(矩形:)當視圖重繪

我已經實現具有彎曲底部邊界上面我的滾動視圖坐在一個梯度層的可摺疊頭視圖。該頭文件具有繪製在其繪製(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()   
} 
+0

我不知道,如果你需要'setNeedsDisplay'等給出了答案,而是 - 你設置'繪製一個斷點(RECT;)'?以下是我關心的內容:您的漸變位於「if!self.didSetGradient」內部,以及第二次*調用事件如何執行此操作?是否有某個地方?重置*'didSetGradient'? – dfd

+0

@dfd我不需要'setNeedsDisplay',但是每當需要更新視圖時都會調用'draw(rect:)'函數,那就是當我遇到問題時。我調用'setNeedsDisplay'來強制重繪視圖來幫助調試。 'self.didSetGradient'是一個var類,當視圖被實例化時被聲明爲false,所以漸變只被設置一次。如果沒有這個條件,那麼在重繪視圖時第二次設置漸變時不能正確遮罩。對這個和陰影的建議將非常感謝! –

+0

現在刪除了一個答案,建議調用'setNeedsDisplay'。我正在引用這個。我同意'draw(rect :)是代碼的正確位置。但是......一旦你將'didSetGradient'設置爲true - 意味着* first *時間的事物被繪製 - 它是如何被設置爲false的?除非將其設置爲false *,然後重繪,否則不會重繪漸變。 – dfd

回答

0

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 
}