Search code examples
iosuiimageviewswift3uicolorcagradientlayer

Add a gradient on UIImageView


I am trying to add a sublayer on my UIImageView but it doesn't work.

  • I have a set of 10 images named from photo0 to photo9 and I display it with a timer of 5s.
  • The outlet shanghaiImage is my background

I would like to add a gradient on top of this marty like: transparent (top) to black (bottom).

Thanks for the help :)

Here is my code in Swift 3.

This part is fine :

import UIKit

class ViewController: UIViewController {

@IBOutlet weak var shanghaiImage: UIImageView!

// beginning index
var _curentImageIndex:Int = 0
// number of images
let NUMBER_OF_IMAGES:Int = 10
// creation of the Timer
var _uiTimer:Timer?


override func viewDidLoad() {
    super.viewDidLoad()
    showPhoto(atIndex: _curentImageIndex)
}

// MARK TIMER ---------

func selectNewTimer(){
    if let existingTimer:Timer = _uiTimer{
        existingTimer.invalidate()
    }
    _uiTimer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(ViewController.showNextImage), userInfo: nil, repeats: true)
}

It's here where there is a problem. I don't know why it's not working.

// MARK PHOTO ---------
func showPhoto(atIndex index:Int){

    let photoName:String =  "photo\(index)"
    shanghaiImage.image =  UIImage(named: photoName)

    let gradient = CAGradientLayer()
    gradient.frame = shanghaiImage.bounds
    let startColor = UIColor(colorLiteralRed: 0, green: 0, blue: 0, alpha: 1)
    let endColor = UIColor.black

    gradient.colors = [startColor, endColor]
    shanghaiImage.layer.insertSublayer(gradient, at: 0)


    _curentImageIndex  =  index
    selectNewTimer()
    }

func showNextImage() {
    var nextPhotoIndex:Int = _curentImageIndex + 1
        if nextPhotoIndex >= NUMBER_OF_IMAGES {
            nextPhotoIndex = 0
        }
    showPhoto(atIndex: nextPhotoIndex)
}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
}

Solution

  • I would suggest putting a UIView with the gradient on top of the UIImageView:

    @IBOutlet weak var shanghaiImage: UIImageView!
    
    let view = UIView(frame: profileImageView.frame)
    
    let gradient = CAGradientLayer()
    
    gradient.frame = view.frame
    
    gradient.colors = [UIColor.clear.cgColor, UIColor.black.cgColor]
    
    gradient.locations = [0.0, 1.0]
    
    view.layer.insertSublayer(gradient, at: 0)
    
    shanghaiImage.addSubview(view)
    
    shanghaiImage.bringSubview(toFront: view)
    

    Objective-C:

    UIView *view = [[UIView alloc] initWithFrame: profileImageView.frame];
    
    CAGradientLayer *gradient = [[CAGradientLayer alloc] init];
    
    gradient.frame = view.frame;
    
    gradient.colors = @[ (id)[[UIColor clearColor] CGColor], (id)[[UIColor blackColor] CGColor] ];
    
    gradient.locations = @[@0.0, @1.0];
    
    [view.layer insertSublayer: gradient atIndex: 0];
    
    [shanghaiImage addSubview: view];
    
    [shanghaiImage bringSubviewToFront: view];