2017-12-18 229 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