透明渐变在UIView类中不起作用

时间:2020-03-16 11:34:53

标签: ios swift uiview

我正在尝试向UIView类中的UIView添加透明渐变,但是它不起作用。

class RecipesDetailsView: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)
        layoutUI()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    lazy var containerView: UIView = {
        let containerView = UIView()
        containerView.backgroundColor = .white
        let gradientMaskLayer = CAGradientLayer()
        gradientMaskLayer.frame = containerView.bounds
        gradientMaskLayer.colors = [UIColor.clear.cgColor, UIColor.white.cgColor]
        gradientMaskLayer.locations = [0, 1]
        containerView.layer.mask = gradientMaskLayer
        containerView.fadeView(style: .bottom, percentage: 0.5)
        containerView.translatesAutoresizingMaskIntoConstraints = false
        return containerView
    }()

    lazy var startCookingButton: UIButton = {
        let startCookingButton = UIButton(type: .system)
        startCookingButton.setTitle("Start cooking", for: .normal)
        startCookingButton.setTitleColor(.white, for: .normal)
        startCookingButton.backgroundColor = .CustomGreen()
        startCookingButton.layer.cornerRadius = 8.0
        startCookingButton.translatesAutoresizingMaskIntoConstraints = false
        startCookingButton.titleLabel?.font = UIFont(name: "AvenirNext-Bold", size: 14)
        return startCookingButton
    }()

    lazy var saveButton: UIButton = {
        let saveButton = UIButton(type: .system)
        saveButton.setTitleColor(.customDarkGray(), for: .normal)
        saveButton.setTitle("Save", for: .normal)
        saveButton.setImage(UIImage(systemName: "heart"), for: .normal)
        saveButton.imageEdgeInsets = UIEdgeInsets(top: 0,left: -5,bottom: 0,right: 0)
        saveButton.titleEdgeInsets = UIEdgeInsets(top: 0,left: 0,bottom: 0,right: -5)
        saveButton.titleLabel?.font = UIFont(name: "AvenirNext-Bold", size: 14)
        saveButton.tintColor = .customDarkGray()
        saveButton.backgroundColor = .clear
        saveButton.translatesAutoresizingMaskIntoConstraints = false
        return saveButton
    }()

    func setupContainerViewConstraints() {
        NSLayoutConstraint.activate([
            containerView.bottomAnchor.constraint(equalTo: bottomAnchor),
            containerView.leadingAnchor.constraint(equalTo: leadingAnchor),
            containerView.trailingAnchor.constraint(equalTo: trailingAnchor),
            containerView.heightAnchor.constraint(equalToConstant: frame.width / 5)
        ])
    }

    func setupStartCookingButton() {
        NSLayoutConstraint.activate([
            startCookingButton.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16),
            startCookingButton.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -32),
            startCookingButton.heightAnchor.constraint(equalToConstant: 55),
            startCookingButton.widthAnchor.constraint(equalToConstant: frame.width * (2.5/4))
        ])
    }

    func setupSaveButtonConstraints() {
        NSLayoutConstraint.activate([
            saveButton.centerYAnchor.constraint(equalTo: startCookingButton.centerYAnchor),
            saveButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
            saveButton.heightAnchor.constraint(equalTo: startCookingButton.heightAnchor),
            saveButton.widthAnchor.constraint(equalToConstant: frame.width * (1.2/4))
        ])
    }

    func addSubviews() {
        addSubview(containerView)
        containerView.addSubview(startCookingButton)
        containerView.addSubview(saveButton)
    }

    func layoutUI() {
        addSubviews()
        setupContainerViewConstraints()
        setupStartCookingButton()
        setupSaveButtonConstraints()
    }
}

我想要得到什么:

enter image description here

我从代码中得到什么:

enter image description here

1 个答案:

答案 0 :(得分:0)

图层不会随视图“自动调整大小”,因此您需要将该渐变图层保留为属性,并在视图布局更改时更新其框架。

添加此属性:

private var gradientMaskLayer: CAGradientLayer!

然后,在lazy var containerView: UIView =中进行更改:

let gradientMaskLayer = CAGradientLayer()

收件人:

gradientMaskLayer = CAGradientLayer()

然后,添加此功能:

override func layoutSubviews() {
    super.layoutSubviews()
    gradientMaskLayer.frame = bounds
}

修改

但是,这会将渐变蒙版应用于containerView AND 的子视图(按钮),这可能不是您想要的。

因此,将您的addSubviews()函数更改为:

func addSubviews() {
    addSubview(containerView)

    // add buttons to self, not to containerView
    //containerView.addSubview(startCookingButton)
    //containerView.addSubview(saveButton)
    addSubview(startCookingButton)
    addSubview(saveButton)

}

编辑2

这是一个完整的实现,视图控制器的背景设置为红色:

class TestViewController: UIViewController {

    var rv: RecipesDetailsView!

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .red
    }

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        // with the way you are setting up the layout,
        // we need to add the view here where we know the
        // frame has been setup
        if rv == nil {
            let w = view.frame.width
            let h = w / 5.0 * 2.0
            let t = view.frame.height - h
            rv = RecipesDetailsView(frame: CGRect(x: 0.0, y: t, width: w, height: h))
            view.addSubview(rv)
        }
    }

}

class RecipesDetailsView: UIView {

    // add this var / property
    private var gradientMaskLayer: CAGradientLayer!

    override init(frame: CGRect) {
        super.init(frame: frame)
        layoutUI()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        // layers do not follow frame changes, so update here
        gradientMaskLayer.frame = bounds
    }

    lazy var containerView: UIView = {
        let containerView = UIView()
        containerView.backgroundColor = .white
        gradientMaskLayer = CAGradientLayer()
        gradientMaskLayer.frame = containerView.bounds
        gradientMaskLayer.colors = [UIColor.clear.cgColor, UIColor.white.cgColor]
        gradientMaskLayer.locations = [0, 1]
        containerView.layer.mask = gradientMaskLayer
        //containerView.fadeView(style: .bottom, percentage: 0.5)
        containerView.translatesAutoresizingMaskIntoConstraints = false
        return containerView
    }()

    lazy var startCookingButton: UIButton = {
        let startCookingButton = UIButton(type: .system)
        startCookingButton.setTitle("Start cooking", for: .normal)
        startCookingButton.setTitleColor(.white, for: .normal)
        //startCookingButton.backgroundColor = .CustomGreen()
        startCookingButton.backgroundColor = .systemGreen
        startCookingButton.layer.cornerRadius = 8.0
        startCookingButton.translatesAutoresizingMaskIntoConstraints = false
        startCookingButton.titleLabel?.font = UIFont(name: "AvenirNext-Bold", size: 14)
        return startCookingButton
    }()

    lazy var saveButton: UIButton = {
        let saveButton = UIButton(type: .system)
        //saveButton.setTitleColor(.customDarkGray(), for: .normal)
        saveButton.setTitleColor(.darkGray, for: .normal)
        saveButton.setTitle("Save", for: .normal)
        saveButton.setImage(UIImage(systemName: "heart"), for: .normal)
        saveButton.imageEdgeInsets = UIEdgeInsets(top: 0,left: -5,bottom: 0,right: 0)
        saveButton.titleEdgeInsets = UIEdgeInsets(top: 0,left: 0,bottom: 0,right: -5)
        saveButton.titleLabel?.font = UIFont(name: "AvenirNext-Bold", size: 14)
        //saveButton.tintColor = .customDarkGray()
        saveButton.tintColor = .darkGray
        saveButton.backgroundColor = .clear
        saveButton.translatesAutoresizingMaskIntoConstraints = false
        return saveButton
    }()

    func setupContainerViewConstraints() {
        NSLayoutConstraint.activate([
            containerView.bottomAnchor.constraint(equalTo: bottomAnchor),
            containerView.leadingAnchor.constraint(equalTo: leadingAnchor),
            containerView.trailingAnchor.constraint(equalTo: trailingAnchor),
            containerView.heightAnchor.constraint(equalToConstant: frame.width / 5)
        ])
    }

    func setupStartCookingButton() {
        NSLayoutConstraint.activate([
            startCookingButton.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: 16),
            startCookingButton.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -32),
            startCookingButton.heightAnchor.constraint(equalToConstant: 55),
            startCookingButton.widthAnchor.constraint(equalToConstant: frame.width * (2.5/4))
        ])
    }

    func setupSaveButtonConstraints() {
        NSLayoutConstraint.activate([
            saveButton.centerYAnchor.constraint(equalTo: startCookingButton.centerYAnchor),
            saveButton.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -16),
            saveButton.heightAnchor.constraint(equalTo: startCookingButton.heightAnchor),
            saveButton.widthAnchor.constraint(equalToConstant: frame.width * (1.2/4))
        ])
    }

    func addSubviews() {
        addSubview(containerView)

        // add buttons to self, not to containerView
        //containerView.addSubview(startCookingButton)
        //containerView.addSubview(saveButton)
        addSubview(startCookingButton)
        addSubview(saveButton)

    }

    func layoutUI() {
        addSubviews()
        setupContainerViewConstraints()
        setupStartCookingButton()
        setupSaveButtonConstraints()
    }
}

结果:

enter image description here