[英]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
}
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.