实时改变视图渐变背景

时间:2017-10-16 11:32:43

标签: ios swift uiview gradient layer

我正在使用渐变背景练习更大的应用程序,并创建了这个虚拟应用程序来简化概念。视图具有50/50渐变背景和2行彩色按钮。

我希望用户能够通过点击上下按钮来播放渐变的颜色,以便渐变背景相应地改变按钮颜色。

enter image description here

ViewController的代码如下:

    import UIKit

    class ViewController: UIViewController {

        var currentUpperColor = UIColor.black
        var currentLowerColor = UIColor.white

        override func viewDidLoad() {
            super.viewDidLoad()

            setGradientBackground(lowerColor: currentLowerColor, upperColor: currentUpperColor)
        }

        func setGradientBackground(lowerColor: UIColor, upperColor: UIColor) {

            let gradientLayer = CAGradientLayer()
            gradientLayer.frame = view.bounds
            gradientLayer.colors = [lowerColor.cgColor, upperColor.cgColor]
            gradientLayer.locations = [0.5, 1.0]
            gradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)
            gradientLayer.endPoint = CGPoint(x: 0.0, y: 0.0)

            view.layer.insertSublayer(gradientLayer, at: 0)

        }

        @IBAction func upperColorPicked(_ sender: UIButton) {
            currentUpperColor = sender.backgroundColor!
            setGradientBackground(lowerColor: currentLowerColor, upperColor: currentUpperColor)
        }

        @IBAction func lowerColorPicked(_ sender: UIButton) {
            currentLowerColor = sender.backgroundColor!
            setGradientBackground(lowerColor: currentLowerColor, upperColor: currentUpperColor)
        }

        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }


}

但是当应用程序运行时,按下按钮时没有任何反应。我理解应该进行某种重绘方式,但我不确定如何调用它。

3 个答案:

答案 0 :(得分:3)

原因

view.layer.insertSublayer(gradientLayer, at: 0)

将始终在索引0处插入渐变图层。最初,您创建了一个黑白颜色的图层并添加到位置0.现在,当用户选择新颜色时,您将创建一个新图层并添加索引0,使其成为黑色和白色图层为索引1.因此,只会出现黑白图层

<强>解决方案:

删除旧图层并添加新图层。

第1步:

将gradientLayer声明为实例变量

class ViewController: UIViewController {
    var gradientLayer = CAGradientLayer()
     ....
 }

第2步:

在IBAction中删除旧图层并添加新图层

@IBAction func upperColorPicked(_ sender: UIButton) {
            self.gradientLayer.removeFromSuperlayer()
            currentUpperColor = sender.backgroundColor!
            setGradientBackground(lowerColor: currentLowerColor, upperColor: currentUpperColor)
        }

        @IBAction func lowerColorPicked(_ sender: UIButton) {
            self.gradientLayer.removeFromSuperlayer()
            currentLowerColor = sender.backgroundColor!
            setGradientBackground(lowerColor: currentLowerColor, upperColor: currentUpperColor)
        }

解决方案2 :(不是首选的)

如果你想要堆叠不同颜色的图层(我个人认为没有任何理由这样做,但如果那就是你想要的那样)你可以使用

view.layer.insertSublayer(CALayer(), at: UInt32(view.layer.sublayers?.count ?? 0))

因此请将setGradientBackground修改为

func setGradientBackground(lowerColor: UIColor, upperColor: UIColor) {

            let gradientLayer = CAGradientLayer()
            gradientLayer.frame = view.bounds
            gradientLayer.colors = [lowerColor.cgColor, upperColor.cgColor]
            gradientLayer.locations = [0.5, 1.0]
            gradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)
            gradientLayer.endPoint = CGPoint(x: 0.0, y: 0.0)

            view.layer.insertSublayer(CALayer(), at: UInt32(view.layer.sublayers?.count ?? 0))

        }

答案 1 :(得分:1)

我尝试了您的代码,在这里似乎发现了以下更改:

import UIKit

class GradientController: UIViewController {

    @IBOutlet weak var vwButtonContainer: UIView!

    var currentUpperColor = UIColor.black
    var currentLowerColor = UIColor.white
    var gradientLayer = CAGradientLayer()

    override func viewDidLoad() {
        super.viewDidLoad()

        setGradientBackground(lowerColor: currentLowerColor, upperColor: currentUpperColor)
    }

    func setGradientBackground(lowerColor: UIColor, upperColor: UIColor) {

        if gradientLayer != nil {
           gradientLayer.removeFromSuperlayer()
        }
        gradientLayer = CAGradientLayer()
        gradientLayer.frame = view.bounds
        gradientLayer.colors = [lowerColor.cgColor, upperColor.cgColor]
        gradientLayer.locations = [0.5, 1.0]
        gradientLayer.startPoint = CGPoint(x: 0.0, y: 1.0)
        gradientLayer.endPoint = CGPoint(x: 0.0, y: 0.0)


        let sublayersCount = view.layer.sublayers?.count ?? 0
        view.layer.insertSublayer(gradientLayer, at: UInt32(sublayersCount))

        view.layer.layoutSublayers()
        view.bringSubview(toFront: vwButtonContainer)


    }

    @IBAction func upperColorPicked(_ sender: UIButton) {
        currentUpperColor = sender.backgroundColor!
        setGradientBackground(lowerColor: currentLowerColor, upperColor: currentUpperColor)
    }

    @IBAction func lowerColorPicked(_ sender: UIButton) {
        currentLowerColor = sender.backgroundColor!
        setGradientBackground(lowerColor: currentLowerColor, upperColor: currentUpperColor)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}

故事板布局:

enter image description here

结果:

enter image description here

答案 2 :(得分:0)

代码显示您已将CAGradientLayer()声明为局部变量。因此,这意味着每次要更新按钮时,都会将一个gradientLayer插入/添加到视图中。 该图层必须只添加一次,并且必须根据按钮操作更新颜色。

System.Runtime.InteropServices.Marshal.ReleaseComObject(word)