Прозрачный градиент не работает в классе UIView - PullRequest
0 голосов
/ 16 марта 2020

Я пытаюсь добавить прозрачный градиент к 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 голосов
/ 16 марта 2020

Слои не "автоматически изменяют размер" в своих представлениях, поэтому вам нужно сохранить этот градиентный слой как свойство и обновлять его кадр при изменении макета представления.

Добавить это свойство:

private var gradientMaskLayer: CAGradientLayer!

затем в lazy var containerView: UIView = измените:

let gradientMaskLayer = CAGradientLayer()

на:

gradientMaskLayer = CAGradientLayer()

затем добавьте это веселье c:

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

Редактировать

Однако, это применит маску градиента к containerView И его подпредставлениям (кнопкам), которые это, вероятно, не то, что вы хотите.

Итак, измените addSubviews() веселье c на:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...