Ich möchte UINavigationbar
backgroundColor
auf eine Farbverlaufsfarbe setzen, wo ich sie über ein Array von Farben festlegen möchte, um einen Farbverlauf zu erstellen, idealerweise als zugängliche Methoden in UINavigationBar
, um seine Farbe in diesen Farbverlauf zu ändern.
Irgendwelche Vorschläge? (Abgesehen von der manuellen Einstellung eines Bildes als Hintergrundbild der Navigationsleiste)
Erstellen Sie eine Verlaufsebene und fügen Sie sie als Hintergrund der Navigationsleiste hinzu.
CAGradientLayer *gradient = [CAGradientLayer layer];
gradient.frame = self.navigationController.navigationBar.bounds;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor whiteColor] CGColor], (id)[[UIColor blackColor] CGColor], nil];
[self.navigationController.navigationBar setBackgroundImage:[self imageFromLayer:gradient] forBarMetrics:UIBarMetricsDefault];
Zum Erstellen eines Bildes aus einer Ebene.
- (UIImage *)imageFromLayer:(CALayer *)layer
{
UIGraphicsBeginImageContext([layer frame].size);
[layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return outputImage;
}
In github gibt es noch eine Bibliothek: CRGradientNavigationBar Sie können diese Bibliothek auch verwenden.
Xcode 8.3.1, Swift 3.1
erweiterung CAGradientLayer
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
}
}
erweiterung UINavigationBar
extension UINavigationBar {
func setGradientBackground(colors: [UIColor]) {
var updatedFrame = bounds
updatedFrame.size.height += self.frame.Origin.y
let gradientLayer = CAGradientLayer(frame: updatedFrame, colors: colors)
setBackgroundImage(gradientLayer.createGradientImage(), for: UIBarMetrics.default)
}
}
klasse ViewController
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var colors = [UIColor]()
colors.append(UIColor(red: 221/255, green: 34/255, blue: 13/255, alpha: 1))
colors.append(UIColor(red: 247/255, green: 113/255, blue: 98/255, alpha: 1))
navigationController?.navigationBar.setGradientBackground(colors: colors)
}
}
Hauptplatine
In Swift 3 und Swift 4 :
let gradient = CAGradientLayer()
let sizeLength = UIScreen.main.bounds.size.height * 2
let defaultNavigationBarFrame = CGRect(x: 0, y: 0, width: sizeLength, height: 64)
gradient.frame = defaultNavigationBarFrame
gradient.colors = [UIColor.white.cgColor, UIColor.black.cgColor]
UINavigationBar.appearance().setBackgroundImage(self.image(fromLayer: gradient), for: .default)
So erstellen Sie ein Bild aus einer Ebene:
func image(fromLayer layer: CALayer) -> UIImage {
UIGraphicsBeginImageContext(layer.frame.size)
layer.render(in: UIGraphicsGetCurrentContext()!)
let outputImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return outputImage!
}
In Swift 2 :
let gradient = CAGradientLayer()
let sizeLength = UIScreen.mainScreen().bounds.size.height * 2
let defaultNavigationBarFrame = CGRectMake(0, 0, sizeLength, 64)
gradient.frame = defaultNavigationBarFrame
gradient.colors = [UIColor.whiteColor().CGColor, UIColor.blackColor().CGColor]
UINavigationBar.appearance().setBackgroundImage(self.image(fromLayer: gradient), forBarMetrics: .Default)
So erstellen Sie ein Bild aus einer Ebene:
func image(fromLayer layer: CALayer) -> UIImage {
UIGraphicsBeginImageContext(layer.frame.size)
layer.renderInContext(UIGraphicsGetCurrentContext()!)
let outputImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return outputImage!
}
Dies ist die Lösung, ohne eine Zwischenvariable CAGradientLayer
und nur CoreGraphics
in Swift 3.0 zu verwenden.
Im Wesentlichen erstellt die Methode im Handumdrehen eine UIImage
mit den übergebenen Farbverläufen und legt sie fest.
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()
}
}
Die defer
-Anweisung macht dies viel sauberer als in früheren Versionen . Beachten Sie, dass CGGradient
seit iOS 8.0 verfügbar ist.
Dadurch wird auch der Verlauf von links nach rechts erstellt. Durch Ändern der Parameter von drawLinearGradient
(start
und end
) werden die Positionen verschoben. Dies ist für Ihre Implementierung vorgesehen.
Für Swift 4.2
extension UINavigationBar {
func setGradientBackground(colors: [Any]) {
let gradient: CAGradientLayer = CAGradientLayer()
gradient.locations = [0.0 , 0.5, 1.0]
gradient.startPoint = CGPoint(x: 0.0, y: 1.0)
gradient.endPoint = CGPoint(x: 1.0, y: 1.0)
var updatedFrame = self.bounds
updatedFrame.size.height += self.frame.Origin.y
gradient.frame = updatedFrame
gradient.colors = colors;
self.setBackgroundImage(self.image(fromLayer: gradient), for: .default)
}
func image(fromLayer layer: CALayer) -> UIImage {
UIGraphicsBeginImageContext(layer.frame.size)
layer.render(in: UIGraphicsGetCurrentContext()!)
let outputImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return outputImage!
}
}
Wie benutzt man
self.navigationController?.navigationBar.setGradientBackground(colors: [
UIColor.red.cgColor,
UIColor.green.cgColor,
UIColor.blue.cgColor
])
extension UINavigationBar {
func addGradient(_ toAlpha: CGFloat, _ color: UIColor) {
let gradient = CAGradientLayer()
gradient.colors = [
color.withAlphaComponent(toAlpha).cgColor,
color.withAlphaComponent(toAlpha).cgColor,
color.withAlphaComponent(0).cgColor
]
gradient.locations = [0, 0.8, 1]
var frame = bounds
frame.size.height += UIApplication.shared.statusBarFrame.size.height
frame.Origin.y -= UIApplication.shared.statusBarFrame.size.height
gradient.frame = frame
layer.insertSublayer(gradient, at: 1)
}
}
In Swift 3
let gradient = CAGradientLayer()
let sizeLength = UIScreen.main.bounds.size.height * 2
let defaultNavigationBarFrame = CGRect(x: 0, y: 0, width: sizeLength, height: 64)
gradient.frame = defaultNavigationBarFrame
gradient.colors = [UIColor.white.cgColor, UIColor.black.cgColor]
UINavigationBar.appearance().setBackgroundImage(self.image(fromLayer: gradient), for: .default)
func image(fromLayer layer: CALayer) -> UIImage {
UIGraphicsBeginImageContext(layer.frame.size)
layer.render(in: UIGraphicsGetCurrentContext()!)
let outputImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return outputImage!
}
Swift 5
Um den horizontalen Verlaufshintergrund der Navigationsleiste zusammen mit der Statusleiste zu erstellen, geben Sie diesen Code einfach in die viewDidLoad()
-Methode Ihres Viewcontrollers ein.
self.navigationItem.title = "Gradiant Back Ground"
let gradientLayer = CAGradientLayer()
var updatedFrame = self.navigationController!.navigationBar.bounds
updatedFrame.size.height += UIApplication.shared.statusBarFrame.size.height
gradientLayer.frame = updatedFrame
gradientLayer.colors = [UIColor.green.cgColor, UIColor.blue.cgColor] // start color and end color
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.0) // Horizontal gradient start
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.0) // Horizontal gradient end
UIGraphicsBeginImageContext(gradientLayer.bounds.size)
gradientLayer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
self.navigationController!.navigationBar.setBackgroundImage(image, for: UIBarMetrics.default)
der Ausgabegradient sieht dann so aus.
PROST!
Objective C-Lösung, die auch auf dem iPhone X funktioniert:
- (void)addGradientToNavigationBar
{
CAGradientLayer *gradient = [CAGradientLayer layer];
CGRect gradientFrame = self.navigationController.navigationBar.bounds;
gradientFrame.size.height += [UIApplication sharedApplication].statusBarFrame.size.height;
gradient.frame = gradientFrame;
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor colorGradientUp] CGColor], (id)[[UIColor colorGradientDown] CGColor], nil];
[self.navigationController.navigationBar setBackgroundImage:[self imageFromLayer:gradient] forBarMetrics:UIBarMetricsDefault];
}
- (UIImage *)imageFromLayer:(CALayer *)layer
{
UIGraphicsBeginImageContext([layer frame].size);
[layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *outputImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return outputImage;
}
Dieses erstaunliche Tutorial von Lawrence Tan zeigt, wie man mit barTintColor
und no backgroundImage
einen Farbverlauf einstellt: https://medium.com/Swift2go/add-gradient-to-navigation -bar-in-Swift-9284fe91fea2
CAGradientLayer
Erweiterung
extension CAGradientLayer {
class func primaryGradient(on view: UIView) -> UIImage? {
let gradient = CAGradientLayer()
let flareRed = UIColor(displayP3Red: 241.0/255.0, green: 39.0/255.0, blue: 17.0/255.0, alpha: 1.0)
let flareOrange = UIColor(displayP3Red: 245.0/255.0, green: 175.0/255.0, blue: 25.0/255.0, alpha: 1.0)
var bounds = view.bounds
bounds.size.height += UIApplication.shared.statusBarFrame.size.height
gradient.frame = bounds
gradient.colors = [flareRed.cgColor, flareOrange.cgColor]
gradient.startPoint = CGPoint(x: 0, y: 0)
gradient.endPoint = CGPoint(x: 1, y: 0)
return gradient.createGradientImage(on: view)
}
private func createGradientImage(on view: UIView) -> UIImage? {
var gradientImage: UIImage?
UIGraphicsBeginImageContext(view.frame.size)
if let context = UIGraphicsGetCurrentContext() {
render(in: context)
gradientImage = UIGraphicsGetImageFromCurrentImageContext()?.resizableImage(withCapInsets: UIEdgeInsets.zero, resizingMode: .stretch)
}
UIGraphicsEndImageContext()
return gradientImage
}
}
Wenden Sie den Farbverlauf an
guard
let navigationController = navigationController,
let flareGradientImage = CAGradientLayer.primaryGradient(on: navigationController.navigationBar)
else {
print("Error creating gradient color!")
return
}
navigationController.navigationBar.barTintColor = UIColor(patternImage: flareGradientImage)
Dies ist ein Framework für verschiedene UI-Komponenten. Der Farbverlauf umfasst die UINavigation-Leiste: Linkbeschreibung hier eingeben
erstens: dann in deinem root ViewController, dass er in einen UINavigationController eingebettet ist
import SHNDStuffs
fügen Sie dies in Ihr ViewDidLoad () ein
class RootViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
SHNDNavigationBarGradient(firstColor: .darkGray,
secondColor: .white,
tintColor: .black,
isHorizontal: true)
}