简体   繁体   English

如何使用 iOS 11 为 UINavigationBar 设置背景渐变并喜欢大标题?

[英]How do I set a background gradient to a UINavigationBar with iOS 11 and prefersLargeTitles?

In iOS 10, I could do this to make a background gradient:在 iOS 10 中,我可以这样做来制作背景渐变:

let gradientColor = UIColor.gradientWithFrame(frame: navigationBar.bounds, colors: [.red, .blue])
navigationBar.barTintColor = gradientColor

Now, navigationBar.bounds returns the size of the UINavigationBar when it doesn't have large titles.现在, navigationBar.bounds在没有大标题时返回UINavigationBar的大小。 This is apparent in this screenshot with the gradient repeating:这在此屏幕截图中很明显,渐变重复:

在此处输入图片说明

You can see that the gradient starts to repeat because the size returned by navigationBar.size returns the incorrect size.您可以看到渐变开始重复,因为由navigationBar.size返回的大小返回了不正确的大小。

Is there another way to set a gradient on UINavigationBar ?还有另一种方法可以在UINavigationBar上设置渐变吗?

You need to account for the status bar height which is 20 on my 6s device you can use UIApplication.shared.statusBarFrame.height and simply add this height to the frame.您需要考虑状态栏高度,在我的 6s 设备上为 20,您可以使用UIApplication.shared.statusBarFrame.height并将此高度添加到框架中。

also, I am setting the gradient by creating a UIImage from a CAGradientLayer so I could use the UIColor(patternImage:) method.此外,我通过从 CAGradientLayer 创建 UIImage 来设置渐变,以便我可以使用UIColor(patternImage:)方法。

import UIKit

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()

    self.navigationController?.navigationBar.prefersLargeTitles = true  
    self.title = "Feed me Seymour"

    if let navFrame = self.navigationController?.navigationBar.frame {

        //HERE
        //Create a new frame with the default offset of the status bar
        let newframe = CGRect(origin: .zero, size: CGSize(width: navFrame.width, height: (navFrame.height + UIApplication.shared.statusBarFrame.height) ))

        let image = gradientWithFrametoImage(frame: newframe, colors: [UIColor.red.cgColor, UIColor.blue.cgColor])!

        self.navigationController?.navigationBar.barTintColor = UIColor(patternImage: image)

    }

}

func gradientWithFrametoImage(frame: CGRect, colors: [CGColor]) -> UIImage? {
    let gradient: CAGradientLayer  = CAGradientLayer(layer: self.view.layer)
    gradient.frame = frame
    gradient.colors = colors
    UIGraphicsBeginImageContext(frame.size)
    gradient.render(in: UIGraphicsGetCurrentContext()!)
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return image
}

导航栏视图 显示 +20 到 y 偏移量的视图层次结构

Try this:试试这个:

    let gradientLayer = CAGradientLayer()
    var updatedFrame = self.navigationController!.navigationBar.bounds
    updatedFrame.size.height += view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0
    gradientLayer.frame = updatedFrame
    gradientLayer.colors = [UIColor.red.cgColor, UIColor.blue.cgColor]
    gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0)
    gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.0)
    UIGraphicsBeginImageContext(gradientLayer.bounds.size)
    gradientLayer.render(in: UIGraphicsGetCurrentContext()!)
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    self.navigationController!.navigationBar.setBackgroundImage(image, for: UIBarMetrics.default)

    let appearance = navigationController!.navigationBar.standardAppearance.copy()
    appearance.backgroundImage = image
    navigationController?.navigationBar.standardAppearance = appearance
    navigationController?.navigationBar.scrollEdgeAppearance = appearance  

我会将导航栏色调设置为“清除颜色”并将渐变添加到背景视图中。

Simply add extension to UIColor只需添加扩展到 UIColor

extension UIColor {
    static func gradientColor(startColor: UIColor, endColor: UIColor, frame: CGRect) -> UIColor? {
        let gradient = CAGradientLayer(layer: frame.size)
        gradient.frame = frame
        gradient.colors = [startColor.cgColor, endColor.cgColor]
        gradient.startPoint = CGPoint(x: 0.0, y: 1.0)
        gradient.endPoint = CGPoint(x: 1.0, y: 1.0)
        UIGraphicsBeginImageContext(frame.size)
        guard let context = UIGraphicsGetCurrentContext() else { return nil }
        gradient.render(in: context)
        guard let image = UIGraphicsGetImageFromCurrentImageContext() else { return nil }
        UIGraphicsEndImageContext()
        return UIColor(patternImage: image)
    }
}

execute:执行:

if let navFrame = self.navigationController?.navigationBar.frame {

    let newframe = CGRect(origin: .zero, size: CGSize(width: navFrame.width, height: (navFrame.height + UIApplication.shared.statusBarFrame.height) ))

    self.navigationController?.navigationBar.barTintColor = UIColor.gradientColor(startColor: .systemPink, endColor: .orange, frame: newframe)

}

在此处输入图片说明

and combine with start/end point to add gradient horizontal/vertical并结合起点/终点添加渐变水平/垂直

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM