UIView 和屏幕旋转上的对角线渐变背景



我正在尝试将UIView的背景设置为渐变。 我的UIViewController viewDidLoad方法中有以下内容:

let gradientLayer = CAGradientLayer()
gradientLayer.colors = [UIColor.blue70.cgColor, UIColor.blue60.cgColor, UIColor.blue70.cgColor]
gradientLayer.startPoint = CGPoint(x: 0, y: 0)
gradientLayer.endPoint = CGPoint(x: 1, y: 1 )
gradientLayer.frame = self.view.bounds
self.view.layer.insertSublayer(gradientLayer, at: 0)

渐变按预期呈现。 但是,当我旋转设备时,渐变不会重绘,并且不再正确渲染。 从纵向>横向旋转会给我留下右侧或左侧的空白部分。 从横向>纵向旋转,我在底部留下了一个空白部分。 我尝试将此代码移动到viewDidLayoutSubviews,但这并没有解决它。 关于如何实现此目的的任何建议?

我在这里建议在viewWillLayoutSubviews((方法中添加渐变

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    self.view.addGradiant()
}

但是现在我们必须删除旧层 当添加新图层时,使用新框架(以防手机旋转(

然后,我们可以先删除该层并添加新层,就像在此扩展方法中一样

extension UIView {
func addGradiant() {
    let GradientLayerName = "gradientLayer"
    if let oldlayer = self.layer.sublayers?.filter({$0.name == GradientLayerName}).first {
        oldlayer.removeFromSuperlayer()
    }
    let gradientLayer = CAGradientLayer()
    gradientLayer.colors = [UIColor.blue.cgColor, UIColor.red.cgColor, UIColor.green.cgColor]
    gradientLayer.startPoint = CGPoint(x: 0, y: 0)
    gradientLayer.endPoint = CGPoint(x: 1, y: 1 )
    gradientLayer.frame = self.bounds
    gradientLayer.name = GradientLayerName
    self.layer.insertSublayer(gradientLayer, at: 0)
}
}

创建梯度层视图控制器的属性。

let gradientLayer = CAGradientLayer()

在 viewDidLoad 中添加渐变层,方法与你相同。

在视图中设置框架将布局子视图

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    gradientLayer.frame = self.view.bounds
}

虽然您可以按照其他答案的建议进行操作并在viewDidLayoutSubviews中更新您的梯度层边界,但更可重用的方法是制作一个梯度视图子类,该子类layerClass是一个CAGradientLayer。 这样的视图将自动调整其图层的大小以适应视图(因为渐变图层现在是视图的支撑层,而不是某个子图层(,并且只需在笔尖文件或情节提要中更改视图的类,即可在任何地方使用此视图:

class GradientView: UIView {
    var colors: [UIColor] = [.red, .white] {
        didSet {
            setup()
        }
    }
    var locations: [CGFloat] = [0,1] {
        didSet {
            setup()
        }
    }
    var startPoint: CGPoint = .zero  {
        didSet {
            setup()
        }
    }
    var endPoint: CGPoint = CGPoint(x: 1, y: 1) {
        didSet {
            setup()
        }
    }
    override class var layerClass : AnyClass { return CAGradientLayer.self }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setup()
    }
    override func awakeFromNib() {
        super.awakeFromNib()
        setup()
    }
    private func setup() {
        guard let layer = self.layer as? CAGradientLayer else {
            return
        }
        layer.colors = colors.map { $0.cgColor }
        layer.locations = locations.map { NSNumber(value: Double($0)) }
        layer.startPoint = startPoint
        layer.endPoint = endPoint
    }
}

最新更新