How can I set the UINavigationbar with gradient co

2019-01-10 09:08发布

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, ideally, as accessible methods inside UINavigationBar to change its color to this gradient.

Any suggestions? (Aside from setting an image manually as the background image of the navigation bar)

7条回答
Juvenile、少年°
2楼-- · 2019-01-10 09:47

This is the solution without using an intermediate CAGradientLayer, and just using CoreGraphics, in Swift 3.0.

Essentially, the method creates a UIImage on the fly with the gradient colors passed and sets it.

extension UINavigationBar
{
    /// Applies a background gradient with the given colors
    func apply(gradient colors : [UIColor]) {
        var frameAndStatusBar: CGRect = self.bounds
        frameAndStatusBar.size.height += 20 // add 20 to account for the status bar

        setBackgroundImage(UINavigationBar.gradient(size: frameAndStatusBar.size, colors: colors), for: .default)
    }

    /// Creates a gradient image with the given settings
    static func gradient(size : CGSize, colors : [UIColor]) -> UIImage?
    {
        // Turn the colors into CGColors
        let cgcolors = colors.map { $0.cgColor }

        // Begin the graphics context
        UIGraphicsBeginImageContextWithOptions(size, true, 0.0)

        // If no context was retrieved, then it failed
        guard let context = UIGraphicsGetCurrentContext() else { return nil }

        // From now on, the context gets ended if any return happens
        defer { UIGraphicsEndImageContext() }

        // Create the Coregraphics gradient
        var locations : [CGFloat] = [0.0, 1.0]
        guard let gradient = CGGradient(colorsSpace: CGColorSpaceCreateDeviceRGB(), colors: cgcolors as NSArray as CFArray, locations: &locations) else { return nil }

        // Draw the gradient
        context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: size.width, y: 0.0), options: [])

        // Generate the image (the defer takes care of closing the context)
        return UIGraphicsGetImageFromCurrentImageContext()
    }
}

The defer statement makes this so much clean than prior versions. Be noted that CGGradient are available since iOS 8.0.

Also, this creates the gradient from left to right, tweaking the parameters of drawLinearGradient (start and end) moves the locations. This is up for your implementation.

查看更多
登录 后发表回答