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

时间:2019-07-02 17:22:06

标签: ios random uiview

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

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

1 个答案:

答案 0 :(得分:1)

如果您使用row_ind: 1 | col_ind: 0 row_ind: 1 | col_ind: 1 row_ind: 1 | col_ind: 2 row_ind: 2 | col_ind: 0 row_ind: 2 | col_ind: 1 row_ind: 2 | col_ind: 2 ,则需要为其播种(例如,使用drand48)。快速而肮脏的解决方案是使用从某个参考日期等开始经过的秒数从时间得出的一些值来植入它。

更好的是,我建议改用srand48,它不需要任何种子。

CGFloat.random(in: 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) } } viewDidLayoutSubviews并调整此渐变图层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子类),但是您必须通过处理帧大小更改的更麻烦的过程来弥补这一点。这是您的选择,但我想提供替代方法。