| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 | ////  Created by Jake Lin on 12/4/15.//  Copyright © 2015 IBAnimatable. All rights reserved.//import UIKitpublic protocol GradientDesignable: class {  var gradientMode: GradientMode { get set }  var startColor: UIColor? { get set }  var endColor: UIColor? { get set }  var predefinedGradient: GradientType? { get set }  var startPoint: GradientStartPoint { get set }}// MARK: - UIViewextension GradientDesignable where Self: UIView {  public func configureGradient() {    configureGradient(in: self)  }}// MARK: - NavigationBarextension GradientDesignable where Self: UINavigationBar {  public func configureGradient() {    let navBarFrame = CGRect(x: 0, y: 0, width: bounds.width, height: UIApplication.shared.statusBarFrame.height)    let gradientLayer = makeGradientLayer()    gradientLayer?.frame = navBarFrame    gradientLayer?.cornerRadius = layer.cornerRadius    let image = gradientLayer?.makeImage()    setBackgroundImage(image, for: .default)  }}// MARK: - Layersextension CALayer {  fileprivate func makeImage() -> UIImage? {    UIGraphicsBeginImageContext(frame.size)    render(in: UIGraphicsGetCurrentContext()!)    let outputImage = UIGraphicsGetImageFromCurrentImageContext()    UIGraphicsEndImageContext()    return outputImage  }}// MARK: - Commonextension GradientDesignable {  func configureGradient(in view: UIView) {    view.subviews.filter { $0 is PrivateGradientView }.forEach {      $0.removeFromSuperview()    }    guard let gradientLayer = makeGradientLayer() else {      return    }    gradientLayer.cornerRadius = view.layer.cornerRadius    gradientLayer.frame = view.bounds    let gradientView = PrivateGradientView(frame: view.bounds, gradientLayer: gradientLayer)    view.insertSubview(gradientView, at: 0)  }  private func makeGradientLayer() -> CALayer? {    guard let colors = gradientColors() else {      return nil    }    switch gradientMode {    case .linear:      return makeLinearLayer(colors: colors)    case .radial:      return makeRadialLayer(colors: colors)    case .conical:      return makeConicalLayer(colors: colors)    }  }  private func gradientColors() -> [CGColor]? {    if let startColor = startColor, let endColor = endColor {      return [startColor.cgColor, endColor.cgColor]    } else if let startColor = predefinedGradient?.colors.start, let endColor = predefinedGradient?.colors.end {      return [startColor.cgColor, endColor.cgColor]    }    return nil  }  private func makeLinearLayer(colors: [CGColor]) -> CAGradientLayer {    let layer = CAGradientLayer()    layer.colors = colors    layer.startPoint = startPoint.startPoint    layer.endPoint = startPoint.endPoint    return layer  }  private func makeRadialLayer(colors: [CGColor]) -> RadialGradientLayer {    let layer = RadialGradientLayer()    layer.colors = colors    layer.startPoint = startPoint.startPoint    layer.endPoint = startPoint.endPoint    return layer  }  private func makeConicalLayer(colors: [CGColor]) -> ConicalGradientLayer {    let layer = ConicalGradientLayer()    layer.colors = colors    layer.startPoint = startPoint.startPoint    layer.endPoint = startPoint.endPoint    return layer  }}// MARK: - PrivateGradientViewprivate class PrivateGradientView: UIView {  init(frame: CGRect, gradientLayer: CALayer) {    super.init(frame: frame)    layer.insertSublayer(gradientLayer, at: 0)    autoresizingMask = [.flexibleWidth, .flexibleHeight]  }  required init?(coder aDecoder: NSCoder) {    fatalError("init(coder:) has not been implemented")  }  override class var layerClass: AnyClass {    return CALayer.self  }}
 |