Слои не "автоматически изменяют размер" в своих представлениях, поэтому вам нужно сохранить этот градиентный слой как свойство и обновлять его кадр при изменении макета представления.
Добавить это свойство:
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()
}
}
Результат: