UIView的水平渐变

时间:2018-07-26 12:11:53

标签: ios swift

我正在尝试通过以下方式向UIView添加“水平渐变”

extension UIView {
    func insertHorizontalGradient(_ color1: UIColor, _ color2: UIColor) {
        let gradient = CAGradientLayer()
        gradient.colors = [color1.cgColor, color2.cgColor]
        gradient.transform = CATransform3DMakeRotation(CGFloat.pi / 2, 0, 0, 1)
        gradient.frame = bounds
        layer.insertSublayer(gradient, at: 0)
    }
}


    if let color1 = UIColor(hexString: "364190"), let color2 = UIColor(hexString: "699cf5"){
        self.statusBarView.insertHorizontalGradient(color1, color2)
    }

    if let color1 = UIColor(hexString: "182395"), let color2 = UIColor(hexString: "5497f0"){
        self.navigationBarView.insertHorizontalGradient(color1, color2)
    }

但是在iPhone 6Plus上,它并没有应用于整个UIView。但是在iPhone 6上,它是完美的。

enter image description here

3 个答案:

答案 0 :(得分:3)

每次视图框架更改时,您都必须更新渐变。为此,使用扩展名不是最佳解决方案,因为您必须在所有使用扩展名的UIView.layoutSubviews实例中覆盖UIView。相反,您可以将图层包装到视图中:

@IBDesignable
public class GradientView: UIView {
    private func createGradient() -> CAGradientLayer {
        let gradient = CAGradientLayer()
        gradient.transform = CATransform3DMakeRotation(.pi / 2, 0, 0, 1)
        gradient.frame = bounds
        layer.insertSublayer(gradient, at: 0)
        return gradient
    }

    private var gradient: CAGradientLayer?

    @IBInspectable
    public var color1: UIColor? {
        didSet {
            updateColors()
        }
    }

    @IBInspectable
    public var color2: UIColor? {
        didSet {
            updateColors()
        }
    }

    required public init?(coder: NSCoder) {
        super.init(coder: coder)
        gradient = createGradient()
        updateColors()
    }

    override public init(frame: CGRect) {
        super.init(frame: frame)
        gradient = createGradient()
        updateColors()
    }

    override public func layoutSubviews() {
        super.layoutSubviews()
        gradient?.frame = bounds
    }

    private func updateColors() {
        guard
            let color1 = color1,
            let color2 = color2
        else {
            return
        }

        gradient?.colors = [color1.cgColor, color2.cgColor]
    }
}

然后:

extension UIView {
    func insertHorizontalGradient(_ color1: UIColor, _ color2: UIColor) -> GradientView {
        let gradientView = GradientView(frame: bounds)
        gradientView.color1 = color1
        gradientView.color2 = color2
        gradientView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

        self.insertSubview(gradientView, at 0)
        return gradientView
    }
}

请注意,我已经用两种颜色@IBDesignable制作了视图@IBInspectable,因此您实际上可以在情节提要/ xib中预览渐变。

答案 1 :(得分:1)

您必须在viewDidLayoutSubviews内调用它,因为它包含不在viewDidLoad中的正确帧,还请确保多次调用此函数,因此可以将代码包装一次bool或设置里面只有渐变的帧

答案 2 :(得分:1)

代替gradient.frame = bounds

尝试

 gradient.frame = CGRect(x: bounds.origin.x , y: bounds.origin.y, width: UIScreen.main.bounds.width , height: bounds.height)

当您的视图覆盖全宽时 &这样可以防止viewDidLayoutSubviews多次通话