Ios 如何正确生成随机渐变背景?

Ios 如何正确生成随机渐变背景?,ios,random,uiview,Ios,Random,Uiview,我一直在尝试创建一个函数,每当出现一个新的视图控制器时,它都会生成一个随机的渐变背景,如下面提供的代码所示,但我无法使它正常工作。问题是“随机”颜色总是相同的,并且以相同的顺序生成 import Foundation import UIKit extension UIView { func setGradientBackground() { let redValue = CGFloat(drand48()) let greenValue = CGF

我一直在尝试创建一个函数,每当出现一个新的视图控制器时,它都会生成一个随机的渐变背景,如下面提供的代码所示,但我无法使它正常工作。问题是“随机”颜色总是相同的,并且以相同的顺序生成

import Foundation

import UIKit

extension UIView {

    func setGradientBackground() {

        let redValue = CGFloat(drand48())
        let greenValue = CGFloat(drand48())
        let blueValue = CGFloat(drand48())

        let redValue2 = CGFloat(drand48())
        let greenValue2 = CGFloat(drand48())
        let blueValue2 = CGFloat(drand48())

        let random = UIColor(red: redValue, green: greenValue, blue: blueValue, alpha: 1).cgColor
        let random2 = UIColor(red: redValue2, green: greenValue2, blue: blueValue2, alpha: 1).cgColor

        let gradient = CAGradientLayer()
        gradient.frame = bounds
        gradient.colors = [random, random2]

        return layer.insertSublayer(gradient, at: 0)
    }
}

如果使用
drand48
,则需要对其进行种子设定(例如使用
srand48
)。快速而肮脏的解决方案是,使用从某个参考日期或类似日期起经过的秒数从时间中派生出的某个值对其进行播种

更好的是,我建议使用
CGFloat.random(在:0…1中)
,它不需要任何种子

extension UIView {
    func addGradientBackground() {
        let random = UIColor.random().cgColor
        let random2 = UIColor.random().cgColor

        let gradient = CAGradientLayer()
        gradient.frame = bounds
        gradient.colors = [random, random2]

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

extension UIColor {
    static func random() -> UIColor {
        let red = CGFloat.random(in: 0...1)
        let green = CGFloat.random(in: 0...1)
        let blue = CGFloat.random(in: 0...1)
        return UIColor(red: red, green: green, blue: blue, alpha: 1)
    }
}

值得一提的是,如果视图的大小发生变化(例如,旋转设备等),那么添加子层的技术是有问题的。您必须手动连接到
viewdilayoutsubviews
layoutSubviews
并调整此渐变层
frame
。我可能会建议实际使用一个
UIView
子类来处理这个渐变层

@IBDesignable
class RandomGradientView: UIView {
    override static var layerClass: AnyClass { return CAGradientLayer.self }
    var gradientLayer: CAGradientLayer { return layer as! CAGradientLayer }

    override init(frame: CGRect = .zero) {
        super.init(frame: frame)
        configure()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        configure()
    }

    override func prepareForInterfaceBuilder() {
        super.prepareForInterfaceBuilder()
        gradientLayer.colors = [UIColor.blue.cgColor, UIColor.red.cgColor]
    }
}

private extension RandomGradientView {
    func configure() {
        let random = UIColor.random().cgColor
        let random2 = UIColor.random().cgColor
        gradientLayer.colors = [random, random2]
    }
}
因为这个
UIView
子类实际上指定了用于主背衬层的层类,并且因为主层总是随着视图大小的变化而自动调整大小,所以它将优雅地处理任何大小的变化(包括动画变化)


尽管如此,我还是很欣赏扩展的便利性(您可以将其应用于现有的
UIView
子类),但您必须用更麻烦的处理帧大小更改的过程来抵消这一点。这是您的选择,但我想提供其他选择。

非常感谢!