Ios 如何设置渐变色以在暗模式下查看?

Ios 如何设置渐变色以在暗模式下查看?,ios,swift,xcode,Ios,Swift,Xcode,我想在暗模式下更改渐变颜色。但它并没有改变。设置视图后设置渐变。在明暗模式之间切换时颜色不变 if let layer = layer as? CAGradientLayer { if let startGradientColor = startGradientColor, let endGradientColor = endGradientColor { layer.colors = [startGradientColor.cgColor, endGr

我想在暗模式下更改渐变颜色。但它并没有改变。设置视图后设置渐变。在明暗模式之间切换时颜色不变

 if let layer = layer as? CAGradientLayer {
        if let startGradientColor = startGradientColor, let endGradientColor = endGradientColor {
            layer.colors = [startGradientColor.cgColor, endGradientColor.cgColor]
        } else {
            layer.colors = gradientColors.map {$0.cgColor}
        }
        layer.startPoint = CGPoint(x: 0, y: 0)  // top
        layer.endPoint = CGPoint(x: 1, y: 1)    // bottom
    }

您需要让您的应用程序对特征集合的更改做出反应,如下所示:

extension YourViewController {
    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)

        if #available(iOS 13.0, *) {
            guard traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) else {
                return
            }

            // redraw your layers here
        }
    }
}

您可以使用“动态提供程序”来完成此操作

例如,在自定义渐变视图类中:

var startGradientColorDarkMode: UIColor = .white
var startGradientColorLightMode: UIColor = .black

lazy var myStartColor = UIColor { (traitCollection: UITraitCollection) -> UIColor in
    if traitCollection.userInterfaceStyle == .dark {
        return self.startGradientColorDarkMode
    } else {
        return self.startGradientColorLightMode
    }
}
然后可以在渐变颜色数组中使用
myStartColor.cgColor

下面是一个完整的示例:

class MyGradientView: UIView {

    // default Dark mode - white to orange
    var startGradientColorDarkMode: UIColor = .white
    {
        didSet {
            self.setNeedsLayout()
        }
    }
    var endGradientColorDarkMode: UIColor = .orange
    {
        didSet {
            self.setNeedsLayout()
        }
    }

    // default Light mode - black to blue
    var startGradientColorLightMode: UIColor = .black
    {
        didSet {
            self.setNeedsLayout()
        }
    }
    var endGradientColorLightMode: UIColor = .blue
    {
        didSet {
            self.setNeedsLayout()
        }
    }

    lazy var myStartColor = UIColor { (traitCollection: UITraitCollection) -> UIColor in
        if traitCollection.userInterfaceStyle == .dark {
            return self.startGradientColorDarkMode
        } else {
            return self.startGradientColorLightMode
        }
    }

    lazy var myEndColor = UIColor { (traitCollection: UITraitCollection) -> UIColor in
        if traitCollection.userInterfaceStyle == .dark {
            return self.endGradientColorDarkMode
        } else {
            return self.endGradientColorLightMode
        }
    }

    private var gradientLayer: CAGradientLayer!

    override class var layerClass: AnyClass {
        return CAGradientLayer.self
    }

    override func layoutSubviews() {
        self.gradientLayer = self.layer as? CAGradientLayer
        self.gradientLayer.colors = [myStartColor.cgColor, myEndColor.cgColor]

        self.gradientLayer.startPoint = CGPoint(x: 0, y: 0)  // top
        self.gradientLayer.endPoint = CGPoint(x: 1, y: 1)    // bottom
    }

}

class GradientTestViewController: UIViewController {

    let testView = MyGradientView(frame: CGRect(x: 40, y: 100, width: 240, height: 240))

    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(testView)

        let tapGR = UITapGestureRecognizer(target: self, action: #selector(didTap))
        self.view.addGestureRecognizer(tapGR)

        // just for example
        // change colors from our defaults

        // change dark mode to red-to-yellow
        testView.startGradientColorDarkMode = .red
        testView.endGradientColorDarkMode = .yellow
        // change light mode to darkbown-to-lightBrown
        testView.startGradientColorLightMode = UIColor(red: 0.45, green: 0.3, blue: 0.25, alpha: 1.0)
        testView.endGradientColorLightMode = UIColor(red: 0.8, green: 0.65, blue: 0.3, alpha: 1.0)

    }

    @objc func didTap(tapGR: UITapGestureRecognizer) {
        // we can change the gradient colors on-the-fly
        if testView.startGradientColorDarkMode == UIColor.red {
            // change dark mode to blue-to-cyan
            testView.startGradientColorDarkMode = .blue
            testView.endGradientColorDarkMode = .cyan
            // change light mode to darkGreen-to-lightGreen
            testView.startGradientColorLightMode = UIColor(red: 0.0, green: 0.5, blue: 0.0, alpha: 1.0)
            testView.endGradientColorLightMode = .green
        } else {
            // change dark mode to red-to-yellow
            testView.startGradientColorDarkMode = .red
            testView.endGradientColorDarkMode = .yellow
            // change light mode to darkbown-to-lightBrown
            testView.startGradientColorLightMode = UIColor(red: 0.45, green: 0.3, blue: 0.25, alpha: 1.0)
            testView.endGradientColorLightMode = UIColor(red: 0.8, green: 0.65, blue: 0.3, alpha: 1.0)
        }
    }

}

这就是我所做的,效果很好

SomeGradientView.swift

class SomeGradientView: UIView {

    override open class var layerClass: AnyClass { return GradientLayer.self }

    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        if #available(iOS 13.0, *) {
            if traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
                (layer as? GradientLayer)?.resetGradientColors()
                setNeedsDisplay()
            }
        }
    }
}
class GradientLayer: CAGradientLayer {

    // MARK: - Lifecycle
    override init() {
        super.init()
        setup()
    }

    override init(layer: Any) {
        super.init(layer: layer)
    }

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

    // MARK: - Private
    private func setup() {
        // gradient setup
        resetGradientColors()
        locations = ...
        opacity = 1
    }

    // MARK: - Internal
    /// Used for trait collection color appearance changes
    func resetGradientColors() {
        colors = [UIColor.systemRed, UIColor.systemBlue]
    }
}
GradientLayer.swift

class SomeGradientView: UIView {

    override open class var layerClass: AnyClass { return GradientLayer.self }

    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        if #available(iOS 13.0, *) {
            if traitCollection.hasDifferentColorAppearance(comparedTo: previousTraitCollection) {
                (layer as? GradientLayer)?.resetGradientColors()
                setNeedsDisplay()
            }
        }
    }
}
class GradientLayer: CAGradientLayer {

    // MARK: - Lifecycle
    override init() {
        super.init()
        setup()
    }

    override init(layer: Any) {
        super.init(layer: layer)
    }

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

    // MARK: - Private
    private func setup() {
        // gradient setup
        resetGradientColors()
        locations = ...
        opacity = 1
    }

    // MARK: - Internal
    /// Used for trait collection color appearance changes
    func resetGradientColors() {
        colors = [UIColor.systemRed, UIColor.systemBlue]
    }
}

将代码添加到问题中