CAGradientLayer 未应用于整个屏幕

Posted

技术标签:

【中文标题】CAGradientLayer 未应用于整个屏幕【英文标题】:CAGradientLayer not being applied to whole screen 【发布时间】:2018-07-13 10:59:52 【问题描述】:

我正在尝试将渐变图层应用到屏幕,但令人讨厌的是该图层仅占屏幕的一半。

我认为问题似乎来自这里的这个问题:

descriptionTextView.topAnchor.constraint(equalTo: view.centerYAnchor).isActive = true

这是我第一次使用编程约束,所以我很难看出问题出在哪里。

Here is an image of what happens

下面是代码

class OBP1VC: UIViewController 

    let gradientLayer: CAGradientLayer = 
        let caGradient = CAGradientLayer()
        caGradient.frame = UIScreen.main.bounds
        caGradient.colors = [Colours.brightGreen.cgColor, Colours.midBlue.cgColor]
        caGradient.startPoint = CGPoint(x: 0.0, y: 0.0)
        caGradient.endPoint = CGPoint(x: 1.0, y: 1.0)
        return caGradient
    ()

    let bearImageView: UIImageView = 
        let imageView = UIImageView(image: #imageLiteral(resourceName: "br_flag"))
        imageView.translatesAutoresizingMaskIntoConstraints = false
        return imageView
    ()

    let descriptionTextView: UITextView = 
        let textView = UITextView()
        textView.text = "Hello\n\nWelcome to the new\n\nHome Healthcare"
        textView.translatesAutoresizingMaskIntoConstraints = false
        textView.textAlignment = .center
        textView.isUserInteractionEnabled = false
        textView.font = UIFont(name: Fonts.avenirBlack, size: 20.0)
        return textView
    ()

    override func viewDidLoad() 
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        view.addSubview(bearImageView)
        view.addSubview(descriptionTextView)

        setupLayout()
    

    override func viewDidLayoutSubviews() 
        view.layer.insertSublayer(gradientLayer, at: 0)
    

    private func setupLayout() 

        bearImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        bearImageView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true
        bearImageView.widthAnchor.constraint(equalToConstant: 100).isActive = true
        bearImageView.heightAnchor.constraint(equalToConstant: 100).isActive = true

        descriptionTextView.topAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        descriptionTextView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        descriptionTextView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        descriptionTextView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    

【问题讨论】:

如果我这样做,文本根本不会出现 清除 descriptionTextView 的背景颜色 - descriptionTextView.backgroundColor = UIColor.clear 在设置渐变层后尝试调用 view.layoutIfNeeded() ......在我的情况下,这个问题解决了,我也面临这个问题...... @Pankaj 谢谢,将 textview 颜色设置为 clear 解决了问题! 【参考方案1】:

以上代码中textView的背景色覆盖了渐变布局,清除后渐变可见

您的 setupLayout 方法应如下所示 -

private func setupLayout() 

        bearImageView.backgroundColor = UIColor.red
        bearImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        bearImageView.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true
        bearImageView.widthAnchor.constraint(equalToConstant: 100).isActive = true
        bearImageView.heightAnchor.constraint(equalToConstant: 100).isActive = true

        descriptionTextView.topAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        descriptionTextView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        descriptionTextView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        descriptionTextView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        descriptionTextView.backgroundColor = UIColor.clear
    

【讨论】:

请提供您在上述答案中解决的问题,以便用户也能理解问题 textView 的背景颜色覆盖了渐变布局,所以清除它会使渐变可见。【参考方案2】:

将此类添加到您的项目中,并在情节提要中为您的视图提供此类,您还可以设置渐变颜色和位置,并且可以在情节提要中看到它的两种颜色渐变看看...

import Foundation
import UIKit


@IBDesignable
class GradientView: UIView 

    @IBInspectable var startColor:   UIColor = .black  didSet  updateColors() 
    @IBInspectable var endColor:     UIColor = .white  didSet  updateColors() 
    @IBInspectable var startLocation: Double =   0.05  didSet  updateLocations() 
    @IBInspectable var endLocation:   Double =   0.95  didSet  updateLocations() 
    @IBInspectable var horizontalMode:  Bool =  false  didSet  updatePoints() 
    @IBInspectable var diagonalMode:    Bool =  false  didSet  updatePoints() 

    override class var layerClass: AnyClass  return CAGradientLayer.self 
    var gradientLayer: CAGradientLayer  return layer as! CAGradientLayer 

    func updatePoints() 
        if horizontalMode 
            gradientLayer.startPoint = diagonalMode ? CGPoint(x: 1, y: 0) : CGPoint(x: 0, y: 0.5)
            gradientLayer.endPoint   = diagonalMode ? CGPoint(x: 0, y: 1) : CGPoint(x: 1, y: 0.5)
         else 
            gradientLayer.startPoint = diagonalMode ? CGPoint(x: 0, y: 0) : CGPoint(x: 0.5, y: 0)
            gradientLayer.endPoint   = diagonalMode ? CGPoint(x: 1, y: 1) : CGPoint(x: 0.5, y: 1)
        
    
    func updateLocations() 
        gradientLayer.locations = [startLocation as NSNumber, endLocation as NSNumber]
    
    func updateColors() 
        gradientLayer.colors    = [startColor.cgColor, endColor.cgColor]
    
    override func layoutSubviews() 
        super.layoutSubviews()
        updatePoints()
        updateLocations()
        updateColors()
    

【讨论】:

以上是关于CAGradientLayer 未应用于整个屏幕的主要内容,如果未能解决你的问题,请参考以下文章

如何像屏幕保护程序一样更改 CAGradientLayer 的颜色?

CAGradientLayer 旋转到 Landscape 后只占一半屏幕

如何将 CAGradientLayer 应用于 UINavigationController 背景

UICollectionViewCell - 将不同的 CAGradientLayer 应用于不同的 UIView

在 CAGradientLayer 上方显示 SCNScene

将 CAGradientLayer 应用于单元格时,如何将其中一个单元格的视图向前移动,使其不受渐变的影响?