I've been facing some difficulties trying to apply CAGradientLayer
s on two items in a view controller: a UIView
and a UIButton
. On investigation, when the gradient is applied to both items, only the UIButton
has the gradient on it whereas the UIView
appears transparent.
My gradient is defined as such:
import UIKit
struct K {
struct Design {
static let upGradientLayer: CAGradientLayer = {
let layer = CAGradientLayer()
layer.colors = [upBlue.cgColor, upPurple.cgColor]
layer.startPoint = CGPoint(x: 0.0, y: 0.0)
layer.endPoint = CGPoint(x: 1.0, y: 1.0)
return layer
}()
static let upBlue = UIColor(named: "UP Blue") ?? .systemBlue
static let upPurple = UIColor(named: "UP Purple") ?? .systemPurple
}
}
The function that applies the gradients (I used insertSublayer
) is separated from the main View Controller file. Here's the code for that function:
import UIKit
extension UIButton {
func applyButtonDesign(_ gradientLayer: CAGradientLayer) {
self.layer.insertSublayer(gradientLayer, at: 0)
self.layer.cornerRadius = 10.0
self.layer.masksToBounds = true
}
}
extension UIView {
func applyHeaderDesign(_ gradientLayer: CAGradientLayer) {
self.layer.insertSublayer(gradientLayer, at: 0)
self.layer.cornerRadius = 10.0
self.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
self.clipsToBounds = true
}
}
(Note: It appears that addSublayer
doesn't work either.)
My UI is being created programmatically (without a Storyboard), and I'm fairly new to it. Here's the code for the view controller where the issue is happening:
import UIKit
class WelcomeViewController: UIViewController {
var headerView: UIView!
var descriptionLabel: UILabel!
var focusImageView: UIImageView!
var promptLabel: UILabel!
var continueButton: UIButton!
let headerGradientLayer = K.Design.upGradientLayer
let buttonGradientLayer = K.Design.upGradientLayer
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
let guide = view.safeAreaLayoutGuide
// MARK: Header View
headerView = UIView()
headerView.translatesAutoresizingMaskIntoConstraints = false
headerView.applyHeaderDesign(headerGradientLayer)
view.addSubview(headerView)
NSLayoutConstraint.activate([
headerView.topAnchor.constraint(equalTo: view.topAnchor),
headerView.rightAnchor.constraint(equalTo: view.rightAnchor),
headerView.leftAnchor.constraint(equalTo: view.leftAnchor),
headerView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.25)
])
// MARK: Other items in ViewController
// MARK: Continue Button
continueButton = UIButton()
continueButton.translatesAutoresizingMaskIntoConstraints = false
continueButton.applyButtonDesign(buttonGradientLayer)
continueButton.setTitle("Let's go!", for: .normal)
continueButton.titleLabel?.font = UIFont(name: "Metropolis Bold", size: 22.0)
continueButton.titleLabel?.textColor = .white
continueButton.addTarget(nil, action: #selector(continueButtonPressed), for: .touchUpInside)
view.addSubview(continueButton)
NSLayoutConstraint.activate([
continueButton.topAnchor.constraint(equalTo: promptLabel.bottomAnchor, constant: K.Layout.someSpaceBetween),
continueButton.rightAnchor.constraint(equalTo: view.rightAnchor, constant: -K.Layout.someSpaceBetween),
continueButton.leftAnchor.constraint(equalTo: view.leftAnchor, constant: K.Layout.someSpaceBetween),
continueButton.bottomAnchor.constraint(equalTo: guide.bottomAnchor),
continueButton.heightAnchor.constraint(equalToConstant: 50.0)
])
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
headerGradientLayer.frame = headerView.bounds
buttonGradientLayer.frame = continueButton.bounds
}
// MARK: - Functions
@objc func continueButtonPressed() {
let newViewController = NameViewController()
newViewController.modalPresentationStyle = .fullScreen
newViewController.hero.modalAnimationType = .slide(direction: .left)
self.present(newViewController, animated: true, completion: nil)
}
}
When running on the Simulator, I get the below image that shows the issue. Notice that the gradient is not applied on the UIView
but is on the UIButton
.
What's causing this issue to happen, and how can I resolve this? If there's a fundamental concept that needs to be learned to tackle this issue, do share as well.
question from:
https://stackoverflow.com/questions/65649803/some-views-with-a-cagradientlayer-dont-render-the-gradient