在UIImageView上添加渐变

时间:2016-11-03 15:44:25

标签: ios uiimageview swift3 uicolor cagradientlayer

我正在尝试在UIImageView上添加子图层,但它不起作用。

  • 我有一组10个图像,从photo0photo9,我显示 它的计时器为5秒。
  • 插座shanghaiImage是我的背景

我想在这个marty上添加一个渐变,如:透明(顶部)到黑色(底部)。

感谢您的帮助:)

这是我在Swift 3中的代码。

这部分很好:

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)
}

这里出现问题。我不知道为什么它不起作用。

// 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.
}
}

5 个答案:

答案 0 :(得分:14)

我建议在UIView顶部放置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)

目标-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];

答案 1 :(得分:11)

你可以使用扩展名来获取swift 3,swift 4和swift 5

为UIImageView的扩展创建一个新文件,如UIImageView_extension.swift,并设置为以下代码:

UIImageView扩展了UIView,因此如果你将UIImageView更改为UIView,那么它会变得更加动态,但是可以被所有扩展UIView的组件使用。所以我用UIView而不是UIImageView。

import UIKit

extension UIView{
   // For insert layer in Foreground
   func addBlackGradientLayerInForeground(frame: CGRect, colors:[UIColor]){
    let gradient = CAGradientLayer()
    gradient.frame = frame
    gradient.colors = colors.map{$0.cgColor}
    self.layer.addSublayer(gradient)
   }
   // For insert layer in background
   func addBlackGradientLayerInBackground(frame: CGRect, colors:[UIColor]){
    let gradient = CAGradientLayer()
    gradient.frame = frame
    gradient.colors = colors.map{$0.cgColor}
    self.layer.insertSublayer(gradient, at: 0)
   }
}

在ViewController.swift中你可以使用它:

class myViewController: UIViewController{
    @IBOutlet weak var imageView: UIImageView!

    override func viewDidLoad() {
    super.viewDidLoad()

        imageView.addBlackGradientLayerInBackground(frame: view.bounds, colors:[.clear, .black])
        //Alternative
        //imageView.addBlackGradientLayerInBackground(frame: imageView.frame, colors: [.clear, .black])
    }
}

此功能需要一个框架,因此您只需要一个来自视图的框架或您自己的imageView。总是像通用功能一样思考,然后你可以在其他视图中更改渐变颜色而不会出现麻烦。

答案 2 :(得分:2)

在Swift 5.1中,我创建了一个自定义类,该类继承自UIImageView并支持多种渐变配置。

import UIKit
import SnapKit

class GradientImageView: UIImageView {

    //MARK: - View model
    enum GradientDirection {
        case upDown
        case downUp
        case leftRight
        case rightLeft
        case topLeftBottomRight
        case topRightBottomLeft
        case bottomLeftTopRight
        case bottomRightTopLeft
    }
    
    //MARK: - Properties
    var colors: [UIColor] = [] {
        didSet {
            updateGradient()
        }
    }
    private var cgColors: [CGColor] {
        return colors.map({ $0.cgColor })
    }
    var gradientDirection: GradientDirection = .downUp {
        didSet {
            updateGradient()
        }
    }
    private lazy var gradientLayer: CAGradientLayer = {
        let layer = CAGradientLayer()
    
        layer.shouldRasterize = true
        
        return layer
    }()
    
    
    //MARK: UI
    private lazy var overlayView: UIView = { return UIView() }()
    
    
    //MARK: - Constructor
    init(colors: [UIColor], gradientDirection: GradientDirection) {
        super.init(frame: .zero)
        
        self.colors = colors
        self.gradientDirection = gradientDirection
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
}


//MARK: - Lifecycle methods methods
extension GradientImageView {
    
    override func didMoveToSuperview() {
        super.didMoveToSuperview()
        
        if superview != nil {
            setupUI()
            updateGradient()
        }
        
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        gradientLayer.frame = overlayView.frame
    
    }
    
}


//MARK: - Private methods
private extension GradientImageView {
    
    func setupUI() {
        addSubview(overlayView)
        //With Snapkit
        overlayView.snp.makeConstraints { (maker) in
            maker.edges.equalToSuperview()
        }

        //Without Snapkit
        //overlayView.translatesAutoresizingMaskIntoConstraints = false
        //overlayView.topAnchor.constraint(equalTo: overlayView.superview!.topAnchor).isActive = true
        //overlayView.leftAnchor.constraint(equalTo: overlayView.superview!.leftAnchor).isActive = true
        //overlayView.bottomAnchor.constraint(equalTo: overlayView.superview!.bottomAnchor).isActive = true
        //overlayView.rightAnchor.constraint(equalTo: overlayView.superview!.rightAnchor).isActive = true

        overlayView.layer.addSublayer(gradientLayer)
    }
    
    func updateGradient() {
        
        gradientLayer.colors = cgColors
        
        switch gradientDirection {
        case .upDown:
            gradientLayer.startPoint = CGPoint(x: 0.5, y: 0)
            gradientLayer.endPoint = CGPoint(x: 0.5, y: 1)
        case .downUp:
            gradientLayer.startPoint = CGPoint(x: 0.5, y: 1)
            gradientLayer.endPoint = CGPoint(x: 0.5, y: 0)
        case .leftRight:
            gradientLayer.startPoint = CGPoint(x: 0, y: 0.5)
            gradientLayer.endPoint = CGPoint(x: 1, y: 0.5)
        case .rightLeft:
            gradientLayer.startPoint = CGPoint(x: 1, y: 0.5)
            gradientLayer.endPoint = CGPoint(x: 0, y: 0.5)
        case .topLeftBottomRight:
            gradientLayer.startPoint = CGPoint(x: 0, y: 0)
            gradientLayer.endPoint = CGPoint(x: 1, y: 1)
        case .topRightBottomLeft:
            gradientLayer.startPoint = CGPoint(x: 1, y: 0)
            gradientLayer.endPoint = CGPoint(x: 0, y: 1)
        case .bottomLeftTopRight:
            gradientLayer.startPoint = CGPoint(x: 0, y: 1)
            gradientLayer.endPoint = CGPoint(x: 1, y: 0)
        case .bottomRightTopLeft:
            gradientLayer.startPoint = CGPoint(x: 1, y: 1)
            gradientLayer.endPoint = CGPoint(x: 0, y: 0)
        }
        
    }
    
}

用法

let gradientImageView = GradientImageView(colors: [YOUR COLORS], gradientDirection: .upDown)
gradientImageView.image = //YOUR Image

答案 3 :(得分:0)

extension UIView {

    func addGradient(frame: CGRect) {
        let gradientView = UIView(frame: self.frame)
        let gradientLayer = CAGradientLayer()
        gradientLayer.frame = frame
        gradientLayer.colors = [UIColor.clear.cgColor, UIColor.black.cgColor]
        gradientLayer.locations = [0.0, 1.0]
        gradientView.layer.insertSublayer(gradientLayer, at: 0)
        addSubview(gradientView)
    }
}

使用方法

let headerView = UIImageView(frame: viewFrame)

// Setup frame
let gradientViewFrame = yourGradientFrame;
headerView.addGradient(frame: gradientViewFrame)

答案 4 :(得分:0)

这些解决方案不适用于我。这个答案的灵感来自this。 我有IBOutlet,就像,

@IBOutlet weak var imageView: UIImageView!

然后我添加了这段代码。

let gradient = CAGradientLayer()
gradient.frame = imageView.bounds
gradient.contents = imageView.image?.cgImage
gradient.colors = [UIColor.green.cgColor, UIColor.blue.cgColor]
gradient.startPoint = CGPoint(x: 0, y: 0)
gradient.endPoint = CGPoint(x: 1, y: 1)
imageView.layer.addSublayer(gradient)

它可以按我的意愿工作。最重要的一点是在渐变层中添加内容。