【问题标题】:Changing view gradient background in real time实时更改视图渐变背景
【发布时间】:2017-10-16 11:32:42
【问题描述】:

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

我希望用户能够通过点击上下按钮来使用渐变的颜色,以便渐变背景根据按钮颜色而变化。

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.
        }


}

但是当应用程序运行时,点击按钮时没有任何反应。我知道应该会发生某种视图重绘,但我不知道如何调用它。

【问题讨论】:

  • 你累了吗layoutSubviews
  • 我认为您每次都在插入一个新的“子图层”,这就是 UI 不会改变的原因。
  • 您是否尝试过删除之前的渐变(=layout)?你只是总是在当前渐变下插入一个新的渐变(在 z 级别),当然它是不可见的,因为另一层覆盖了它。

标签: ios swift uiview gradient layer


【解决方案1】:

原因

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))

        }

【讨论】:

  • 谢谢!我真的不需要叠加渐变层,所以你的解决方案非常优雅高效)
  • @Denys Triasunov : 很高兴该解决方案对你有用 :) 快乐编码 :)
【解决方案2】:

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

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.
    }


}

故事板布局:

结果:

【讨论】:

  • 你的最后一张照片有一些奇怪的美丽,它只是......令人惊叹。不过干得好!
【解决方案3】:

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

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

override func viewDidLoad() {
    super.viewDidLoad()
    setGradientBackground(lowerColor: currentLowerColor, upperColor: currentUpperColor)
}
func setGradientBackground(lowerColor: UIColor, upperColor: UIColor) {
    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!
    gradientLayer.colors = [currentLowerColor.cgColor, currentUpperColor.cgColor]
}
@IBAction func lowerColorPicked(_ sender: UIButton) {
    currentLowerColor = sender.backgroundColor!
    gradientLayer.colors = [currentLowerColor.cgColor, currentUpperColor.cgColor]
}

【讨论】:

    猜你喜欢
    • 2022-10-14
    • 1970-01-01
    • 2022-09-29
    • 1970-01-01
    • 2021-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多