2017-12-18 233 views
3

我想在所有視圖中放入漸變背景。用UIView繪製漸變畫()用swift

我認爲這樣做的方式不需要在所有視圖控制器中創建視圖的IBOutlet,就是從UIView創建一個新類,然後在draw()中放入使CAGradientLayer成爲代碼的代碼風景。

因此,在界面生成器中,我只需要選擇背景視圖並將其類設置爲我的自定義類。它到目前爲止工作。

我的問題是如果我可以做到這一點沒有問題。有人知道可以嗎? 因爲從UIView繼承的模型文件附帶註釋: //如果執行自定義繪圖,則只能覆蓋draw()。

而且我不知道是否創建圖層數量。或者,如果draw()僅適用於低級繪圖或類似的東西。對draw()函數的最佳用法一無所知。

這是代碼:

override func draw(_ rect: CGRect) { 

     let layer = CAGradientLayer() 
     layer.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height) 

     let color1 = UIColor(red: 4/255, green: 39/255, blue: 105/255, alpha: 1) 
     let color2 = UIColor(red: 1/255, green: 91/255, blue: 168/255, alpha: 1) 

     layer.colors = [color1.cgColor, color2.cgColor] 
     self.layer.addSublayer(layer) 
    } 
+0

您需要爲您的梯度層的位置屬性,您可以瞭解更多。 –

回答

2

想,你可以使用@IBDesignable@IBInspectable配置從故事板startColor和ENDCOLOR屬性,你可以有儘可能多的顏色。如果要繪製draw(_ rect :)方法,請使用CGGradient指定顏色和位置,而不是CAGradientLayer。簡單漸變類和draw(_ rect: CGRect)功能看起來像這樣

import UIKit 

@IBDesignable class GradientView: UIView { 

    @IBInspectable var startColor: UIColor = UIColor(red: 4/255, green: 39/255, blue: 105/255, alpha: 1) 
    @IBInspectable var endColor: UIColor = UIColor(red: 1/255, green: 91/255, blue: 168/255, alpha: 1) 

    override func draw(_ rect: CGRect) { 

     let context = UIGraphicsGetCurrentContext()! 
     let colors = [startColor.cgColor, endColor.cgColor] 

     let colorSpace = CGColorSpaceCreateDeviceRGB() 

     let colorLocations: [CGFloat] = [0.0, 1.0] 

     let gradient = CGGradient(colorsSpace: colorSpace, 
            colors: colors as CFArray, 
            locations: colorLocations)! 

     let startPoint = CGPoint.zero 
     let endPoint = CGPoint(x: 0, y: bounds.height) 
     context.drawLinearGradient(gradient, 
          start: startPoint, 
          end: endPoint, 
         options: []) 
    } 
} 

heretutorial

+0

謝謝。我認爲我正在尋找更近的人。並且效果很好。 – Aisenhein

+0

使用IBInspectable和IBDesignable的好主意,使它非常完美。 – Aisenhein

+0

它幫助很大。現在,您可以爲Storyboard配置不同視圖的值。 – suhit

0

你不應該添加一個CAGradientLayer的draw函數內。

如果你想一個梯度添加到視圖那麼最簡單的方法是用層做(比如你正在做的),但不喜歡這個......

你應該把它添加到您的視圖init方法的一部分,然後在佈局子視圖方法中更新其框架。

事情是這樣的......

class MyView: UIView { 
    let gradientLayer: CAGradientLayer = { 
     let l = CAGradientLayer() 
     let color1 = UIColor(red: 4/255, green: 39/255, blue: 105/255, alpha: 1) 
     let color2 = UIColor(red: 1/255, green: 91/255, blue: 168/255, alpha: 1) 
     l.colors = [color1.cgColor, color2.cgColor] 
     return l 
    }() 

    override init(frame: CGRect) { 
     super.init(frame: frame) 

     layer.addSublayer(gradientLayer) 
    } 

    override func layoutSubviews() { 
     super.layoutSubviews() 

     gradientLayer.frame = bounds 
    } 
} 
+0

感謝您的回答。但是通過這段代碼,沒有顯示漸變。我只是有一個白色背景(我的視圖本身的顏色)。 我需要調用init(frame)的某個地方嗎?我認爲它從來沒有被稱爲。 xcode需要給我一個init(編碼器),我可以在其內部調用init(幀)嗎? – Aisenhein

0

我想創建的UIView延伸並在需要時使用它。

extension UIView { 
     func withGradienBackground(color1: UIColor, color2: UIColor, color3: UIColor, color4: UIColor) { 
      let layerGradient = CAGradientLayer() 

      layerGradient.colors = [color1.cgColor, color2.cgColor, color3.cgColor, color4.cgColor] 
      layerGradient.frame = bounds 
      layerGradient.startPoint = CGPoint(x: 1.5, y: 1.5) 
      layerGradient.endPoint = CGPoint(x: 0.0, y: 0.0) 
      layerGradient.locations = [0.0, 0.3, 0.4, 1.0] 

      layer.insertSublayer(layerGradient, at: 0) 
     } 
} 

在這裏,您可以更改FUNC聲明指定爲startPointendPointlocations PARAMS作爲變量。

之後,只需調用這個方法就像

gradienView.withGradienBackground(color1: UIColor.green, color2: UIColor.red, color3: UIColor.blue, color4: UIColor.white) 

附: 請注意,您在colors陣列

+0

但是通過這個擴展,我將需要在所有視圖控制器中創建視圖的出口以調用梯度函數。我想避免這種情況。不管怎麼說,還是要謝謝你。 – Aisenhein