How can I set the UINavigationbar with gradient color?

前端 未结 11 696
花落未央
花落未央 2020-11-30 22:27

I want to set the UINavigationbar backgroundColor to a gradient color where I would like to set it via an array of colors to create a Gradient, ide

相关标签:
11条回答
  • 2020-11-30 23:09

    SWIFT 5

    To make the horizontal gradient background of the navigation bar along with status bar too.. just put this code in your viewcontroller's viewDidLoad() method.

        self.navigationItem.title = "Gradiant Back Ground"
        let gradientLayer = CAGradientLayer()
        var updatedFrame = self.navigationController!.navigationBar.bounds
        updatedFrame.size.height += UIApplication.shared.statusBarFrame.size.height
        gradientLayer.frame = updatedFrame
        gradientLayer.colors = [UIColor.green.cgColor, UIColor.blue.cgColor] // start color and end color
        gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0) // Horizontal gradient start
        gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.0) // Horizontal gradient end
        UIGraphicsBeginImageContext(gradientLayer.bounds.size)
        gradientLayer.render(in: UIGraphicsGetCurrentContext()!)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        self.navigationController!.navigationBar.setBackgroundImage(image, for: UIBarMetrics.default)
    

    output Gradient will look like this.

    CHEERS!

    0 讨论(0)
  • 2020-11-30 23:13

    This is a framework for different UI components gradient include UINavigation bar: enter link description here

    first : then in your root ViewController that it embedded into an UINavigationController

    import SHNDStuffs
    

    put this in your ViewDidLoad()

    class RootViewController: UIViewController {
        override func viewDidLoad() {
            super.viewDidLoad()
    
            SHNDNavigationBarGradient(firstColor: .darkGray,
                                      secondColor: .white,
                                      tintColor: .black,
                                      isHorizontal: true)
    }
    
    0 讨论(0)
  • 2020-11-30 23:14

    Details

    • Xcode 11.4 (11E146), swift 5
    • Tested on iOS 13.1, 12.2, 11.0.1

    Solution

    class UINavigationBarGradientView: UIView {
    
        enum Point {
            case topRight, topLeft
            case bottomRight, bottomLeft
            case custom(point: CGPoint)
    
            var point: CGPoint {
                switch self {
                    case .topRight: return CGPoint(x: 1, y: 0)
                    case .topLeft: return CGPoint(x: 0, y: 0)
                    case .bottomRight: return CGPoint(x: 1, y: 1)
                    case .bottomLeft: return CGPoint(x: 0, y: 1)
                    case .custom(let point): return point
                }
            }
        }
    
        private weak var gradientLayer: CAGradientLayer!
    
        convenience init(colors: [UIColor], startPoint: Point = .topLeft,
                         endPoint: Point = .bottomLeft, locations: [NSNumber] = [0, 1]) {
            self.init(frame: .zero)
            let gradientLayer = CAGradientLayer()
            gradientLayer.frame = frame
            layer.addSublayer(gradientLayer)
            self.gradientLayer = gradientLayer
            set(colors: colors, startPoint: startPoint, endPoint: endPoint, locations: locations)
            backgroundColor = .clear
        }
    
        func set(colors: [UIColor], startPoint: Point = .topLeft,
                 endPoint: Point = .bottomLeft, locations: [NSNumber] = [0, 1]) {
            gradientLayer.colors = colors.map { $0.cgColor }
            gradientLayer.startPoint = startPoint.point
            gradientLayer.endPoint = endPoint.point
            gradientLayer.locations = locations
        }
    
        func setupConstraints() {
            guard let parentView = superview else { return }
            translatesAutoresizingMaskIntoConstraints = false
            topAnchor.constraint(equalTo: parentView.topAnchor).isActive = true
            leftAnchor.constraint(equalTo: parentView.leftAnchor).isActive = true
            parentView.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
            parentView.rightAnchor.constraint(equalTo: rightAnchor).isActive = true
        }
    
        override func layoutSubviews() {
            super.layoutSubviews()
            guard let gradientLayer = gradientLayer else { return }
            gradientLayer.frame = frame
            superview?.addSubview(self)
        }
    }
    
    extension UINavigationBar {
        func setGradientBackground(colors: [UIColor],
                                   startPoint: UINavigationBarGradientView.Point = .topLeft,
                                   endPoint: UINavigationBarGradientView.Point = .bottomLeft,
                                   locations: [NSNumber] = [0, 1]) {
            guard let backgroundView = value(forKey: "backgroundView") as? UIView else { return }
            guard let gradientView = backgroundView.subviews.first(where: { $0 is UINavigationBarGradientView }) as? UINavigationBarGradientView else {
                let gradientView = UINavigationBarGradientView(colors: colors, startPoint: startPoint,
                                                               endPoint: endPoint, locations: locations)
                backgroundView.addSubview(gradientView)
                gradientView.setupConstraints()
                return
            }
            gradientView.set(colors: colors, startPoint: startPoint, endPoint: endPoint, locations: locations)
        }
    }
    

    Usage

    navigationBar.setGradientBackground(colors: [.lightGray, .red], startPoint: .topLeft, endPoint: .bottomRight)
    
    0 讨论(0)
  • 2020-11-30 23:16

    Create gradient layer and add it as background of navigation bar.

        CAGradientLayer *gradient = [CAGradientLayer layer];
        gradient.frame = self.navigationController.navigationBar.bounds;
        gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor whiteColor] CGColor], (id)[[UIColor blackColor] CGColor], nil];
        [self.navigationController.navigationBar setBackgroundImage:[self imageFromLayer:gradient] forBarMetrics:UIBarMetricsDefault];
    

    For creating image from layer.

    - (UIImage *)imageFromLayer:(CALayer *)layer
    {
        UIGraphicsBeginImageContext([layer frame].size);
    
        [layer renderInContext:UIGraphicsGetCurrentContext()];
        UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
    
        UIGraphicsEndImageContext();
    
        return outputImage;
    }
    

    One more thing, there is one library available in github : CRGradientNavigationBar you can also use this library.

    0 讨论(0)
  • 2020-11-30 23:16

    Objective C solution that works on iPhone X as well:

    - (void)addGradientToNavigationBar
    {
        CAGradientLayer *gradient = [CAGradientLayer layer];
        CGRect gradientFrame = self.navigationController.navigationBar.bounds;
        gradientFrame.size.height += [UIApplication sharedApplication].statusBarFrame.size.height;
        gradient.frame = gradientFrame;
        gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor colorGradientUp] CGColor], (id)[[UIColor colorGradientDown] CGColor], nil];
        [self.navigationController.navigationBar setBackgroundImage:[self imageFromLayer:gradient] forBarMetrics:UIBarMetricsDefault];
    }
    
    - (UIImage *)imageFromLayer:(CALayer *)layer
    {
        UIGraphicsBeginImageContext([layer frame].size);
    
        [layer renderInContext:UIGraphicsGetCurrentContext()];
        UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
    
        UIGraphicsEndImageContext();
    
        return outputImage;
    }
    
    0 讨论(0)
  • 2020-11-30 23:17

    In Swift 3, Swift 4 and Swift 5:

    let gradient = CAGradientLayer()
    let sizeLength = UIScreen.main.bounds.size.height * 2
    let defaultNavigationBarFrame = CGRect(x: 0, y: 0, width: sizeLength, height: 64)
    
    gradient.frame = defaultNavigationBarFrame
    
    gradient.colors = [UIColor.white.cgColor, UIColor.black.cgColor]
    
    UINavigationBar.appearance().setBackgroundImage(self.image(fromLayer: gradient), for: .default)
    

    For creating image from layer:

    func image(fromLayer layer: CALayer) -> UIImage {
        UIGraphicsBeginImageContext(layer.frame.size)
    
        layer.render(in: UIGraphicsGetCurrentContext()!)
    
        let outputImage = UIGraphicsGetImageFromCurrentImageContext()
    
        UIGraphicsEndImageContext()
    
        return outputImage!
    }
    

    In Swift 2:

    let gradient = CAGradientLayer()
    let sizeLength = UIScreen.mainScreen().bounds.size.height * 2
    let defaultNavigationBarFrame = CGRectMake(0, 0, sizeLength, 64)
    
    gradient.frame = defaultNavigationBarFrame
    
    gradient.colors = [UIColor.whiteColor().CGColor, UIColor.blackColor().CGColor]
    
    UINavigationBar.appearance().setBackgroundImage(self.image(fromLayer: gradient), forBarMetrics: .Default)
    

    For creating image from layer:

    func image(fromLayer layer: CALayer) -> UIImage {    
        UIGraphicsBeginImageContext(layer.frame.size)
    
        layer.renderInContext(UIGraphicsGetCurrentContext()!)
    
        let outputImage = UIGraphicsGetImageFromCurrentImageContext()
    
         UIGraphicsEndImageContext()
    
        return outputImage!
    }
    
    0 讨论(0)
提交回复
热议问题