I have created a UIImageView BackView to create a blurry background with a gradient Layer to black. (To create something like Spotify artists profile.)
I want to place this imageview behind the navigationBar for better looks. But to achieve this, I need a UIImage. I cannot just take BackView.image because this is just the source image without the BlurryView or the gradient Layer.
So I found this code on HackingWithSwift:
let renderer = UIGraphicsImageRenderer(size: rect.size)
let image = renderer.image { ctx in
backView.drawHierarchy(in: backView.bounds, afterScreenUpdates: true)
}
But this does not render the view as it is sadly. It draws just the gradientLayer without anything behind it. Does someone have a code snippet to get all Subviews into the rendered Image?
Below I added my UIImageView-class and the function which handles the renderer:
class BackView: UIImageView {
var thisframe: CGRect
var anImage: UIImage? {
didSet {
setupImage()
}
}
override init(frame: CGRect) {
self.thisframe = frame
super.init(frame: .zero)
self.anImage = UIImage(named: "gray")
setupImage()
}
func setupImage() {
self.image = anImage
self.addSubview(blurry)
self.addSubview(blacky)
gradientLayer.removeFromSuperlayer()
self.layer.insertSublayer(gradientLayer, at: 1)
print(gradientLayer.bounds)
}
lazy var blurry: UIVisualEffectView = {
let blur = UIVisualEffectView()
blur.effect = UIBlurEffect(style: .regular)
blur.frame = (thisframe)
return blur
}()
lazy var blacky: UIImageView = {
let black = UIImageView()
black.backgroundColor = .black
black.alpha = 0.0
black.frame = (thisframe)
return black
}()
lazy var gradientLayer: CAGradientLayer = {
let gradient = CAGradientLayer()
gradient.colors = [UIColor.black.withAlphaComponent(0.0).cgColor,
UIColor.black.withAlphaComponent(1.0).cgColor]
gradient.frame = (thisframe)
gradient.startPoint = CGPoint(x: 0.5, y: 0)
gradient.endPoint = CGPoint(x: 0.5, y: 1)
return gradient
}()
And here the function:
func setupNavBarBackground() {
let renderer = UIGraphicsImageRenderer(size: rect.size)
let image = renderer.image { ctx in
backView.drawHierarchy(in: backView.bounds, afterScreenUpdates: true)
}
self.navigationController?.navigationBar.barTintColor = .clear
self.navigationController?.navigationBar.backgroundColor = .clear
self.navigationController?.navigationBar.setBackgroundImage(image, for: .default)
self.navigationController?.navigationBar.shadowImage = image
}