在iPhone 8上:
在iPhone X上:
问题出在状态栏上。我在这里做的并不是排他性的。只是颜色是渐变色,但这无关紧要。
ViewController的属性:
用于设置渐变的功能:
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!
}
答案 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
}
答案 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!
}
我不会说是完美的解决方案,而是可行的替代方案。