| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- //
- // Created by Jake Lin on 12/4/15.
- // Copyright © 2015 IBAnimatable. All rights reserved.
- //
- import UIKit
- public 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: - UIView
- extension GradientDesignable where Self: UIView {
- public func configureGradient() {
- configureGradient(in: self)
- }
- }
- // MARK: - NavigationBar
- extension 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: - Layers
- extension CALayer {
- fileprivate func makeImage() -> UIImage? {
- UIGraphicsBeginImageContext(frame.size)
- render(in: UIGraphicsGetCurrentContext()!)
- let outputImage = UIGraphicsGetImageFromCurrentImageContext()
- UIGraphicsEndImageContext()
- return outputImage
- }
- }
- // MARK: - Common
- extension 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: - PrivateGradientView
- private 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
- }
- }
|