iPhone X上的UINavigationBar状态栏颜色问题

时间:2018-06-21 15:21:52

标签: ios uinavigationbar iphone-x ios-statusbar

在iPhone 8上:

enter image description here

在iPhone X上:

enter image description here

问题出在状态栏上。我在这里做的并不是排他性的。只是颜色是渐变色,但这无关紧要。

ViewController的属性:

enter image description here

用于设置渐变的功能:

func setNavigationBarAppearence() {
        let gradient = CAGradientLayer()
        let sizeLength = UIScreen.main.bounds.size.height * 2
        let defaultNavigationBarFrame = CGRect(x: 0, y: 0, width: sizeLength, height: self.navigationController.navigationBar.frame.size.height)
        gradient.frame = defaultNavigationBarFrame
        gradient.colors = [UIColor(red: 30/255, green: 234/255, blue: 191/255, alpha: 1).cgColor, UIColor(red: 12/255, green: 198/255, blue: 183/255, alpha: 1).cgColor]
        UINavigationBar.appearance().setBackgroundImage(self.image(fromLayer: gradient), for: .default)
        UINavigationBar.appearance().tintColor = UIColor.white        
    }

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

3 个答案:

答案 0 :(得分:0)

尝试此方法。可以解决您的问题

 /// Applies a background gradient with the given colors
    func apply(gradient colors : [CGColor]) {
        var frameAndStatusBar: CGRect = self.bounds
        frameAndStatusBar.size.height += UIApplication.shared.statusBarFrame.height

        let gradient = CAGradientLayer()
        gradient.frame = frameAndStatusBar
        gradient.colors = colors
//        gradient.locations = [0.0,1.0]
        gradient.startPoint = CGPoint.init(x: 0.0, y: 0.0)
        gradient.endPoint = CGPoint.init(x: 0.0, y: 1.0)
        if let img = self.image(fromLayer: gradient)
        {
            setBackgroundImage(img, for: .default)
        }
    }

    /// Creates a gradient image with the given settings
    func image(fromLayer layer: CALayer) -> UIImage? {
        UIGraphicsBeginImageContext(layer.frame.size)

        if let context =  UIGraphicsGetCurrentContext()
        {
            layer.render(in:context)

            let outputImage = UIGraphicsGetImageFromCurrentImageContext()

            UIGraphicsEndImageContext()

            return outputImage
        }
        return nil
    }

enter image description here

答案 1 :(得分:0)

这是我的用法:

extension CAGradientLayer {
    convenience init(frame: CGRect, colors: [UIColor]) {
        self.init()
        self.frame = frame
        self.colors = []
        for color in colors {
            self.colors?.append(color.cgColor)
        }
        startPoint = CGPoint(x: 0, y: 0)
        endPoint = CGPoint(x: 0, y: 1)
    }

    func createGradientImage() -> UIImage? {
        var image: UIImage? = nil
        UIGraphicsBeginImageContext(bounds.size)
        if let context = UIGraphicsGetCurrentContext() {
            render(in: context)
            image = UIGraphicsGetImageFromCurrentImageContext()
        }
        UIGraphicsEndImageContext()
        return image
    }
}

extension UINavigationBar {
    func setGradientBackground(colors: [UIColor]) {
        var updatedFrame = bounds
        updatedFrame.size.height += self.frame.origin.y 
        // above adjustment is important, otherwise the frame is considered without 
        // the status bar height which in turns causes the gradient layer to be calculated wrong
        let gradientLayer = CAGradientLayer(frame: updatedFrame, colors: colors)
        setBackgroundImage(gradientLayer.createGradientImage(), for: .default)
    }
}

用法:

override func viewDidLoad() {
    ...
    let colors = [UIColor(red: 30/255, green: 234/255, blue: 191/255, alpha: 1), UIColor(red: 12/255, green: 198/255, blue: 183/255, alpha: 1)]
    navigationController?.navigationBar.setGradientBackground(colors: colors)
    ...
}

答案 2 :(得分:0)

这与导航栏+状态栏的总高度有关。我将其修复如下:

func setNavigationBarAppearence() {
        let gradient = CAGradientLayer()
        let sizeLength = UIScreen.main.bounds.size.height * 2
        var defaultNavigationBarFrame = CGRect(x: 0, y: 0, width: sizeLength, height: self.navigationController.navigationBar.frame.size.height)
        if UIDevice().userInterfaceIdiom == .phone {
            if UIScreen.main.nativeBounds.height == 2436{
                defaultNavigationBarFrame.size.height += 44
            } else {
                defaultNavigationBarFrame.size.height += 20
            }
        }

        gradient.frame = defaultNavigationBarFrame
        gradient.colors = [UIColor(red: 30/255, green: 234/255, blue: 191/255, alpha: 1).cgColor, UIColor(red: 12/255, green: 198/255, blue: 183/255, alpha: 1).cgColor]
        UINavigationBar.appearance().setBackgroundImage(self.image(fromLayer: gradient), for: .default)
        UINavigationBar.appearance().tintColor = UIColor.white        
    }

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

我不会说是完美的解决方案,而是可行的替代方案。