Wie stellen Sie in iOS 11 ein benutzerdefiniertes Hintergrundbild für die große Navigationsleiste ein? Ich verwende eine benutzerdefinierte Unterklasse, die ich den navigationControllers im Storyboard zugewiesen habe.
So erstelle ich meine benutzerdefinierte NavBar:
class CustomNavigationController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.navigationBar.tintColor = UIColor(red:1, green:1, blue:1, alpha:0.6)
self.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.white]
if #available(iOS 11.0, *) {
self.navigationBar.prefersLargeTitles = true
self.navigationItem.largeTitleDisplayMode = .automatic
self.navigationBar.largeTitleTextAttributes = [NSForegroundColorAttributeName: UIColor.white]
self.navigationBar.barTintColor = UIColor.green
}
self.navigationBar.isTranslucent = false
self.navigationBar.setBackgroundImage(#imageLiteral(resourceName: "navigationBarBackground"), for: .default)
self.navigationBar.shadowImage = #imageLiteral(resourceName: "navigationBarShadow")
}
}
Seltsamerweise funktioniert die setBackgroundImage(image, for: .default)
nicht für die großen Titel. Hat es vorher mit iOS 10 funktioniert und auch wenn ich das iPhone drehe (und die kleine NavBar aktiviere), ist der Hintergrund wieder da?
Edit: Die backgroundImage
wird noch gerendert, aber irgendwie verborgen. Nur wenn Sie mit dem Scrollen beginnen und die "normale" Navigationsleiste angezeigt wird, ist das backgroundImage sichtbar. Auch das barTintColor
wird in diesem Fall komplett ignoriert .
Ich hatte das gleiche Problem, das durch behoben wurde
Entfernen Sie setBackgroundImage und verwenden Sie die BarTint-Farbe für das Musterbild
let bgimage = imageWithGradient(startColor: UIColor.red, endColor: UIColor.yellow, size: CGSize(width: UIScreen.main.bounds.size.width, height: 1))
self.navigationBar.barTintColor = UIColor(patternImage: bgimage!)
Holen Sie sich ein Bild mit Farbverläufen
func imageWithGradient(startColor:UIColor, endColor:UIColor, size:CGSize, horizontally:Bool = true) -> UIImage? {
let gradientLayer = CAGradientLayer()
gradientLayer.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height)
gradientLayer.colors = [startColor.cgColor, endColor.cgColor]
if horizontally {
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
} else {
gradientLayer.startPoint = CGPoint(x: 0.5, y: 0.0)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 1.0)
}
UIGraphicsBeginImageContext(gradientLayer.bounds.size)
gradientLayer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
In iOS 11 müssen Sie kein Hintergrundbild mehr setzen (Remove deklarieren), wenn Sie große Titel verwenden. Stattdessen müssen Sie BarTintColor verwenden.
class CustomNavigationController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.navigationBar.tintColor = UIColor(red:1, green:1, blue:1, alpha:0.6)
self.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName: UIColor.white]
if #available(iOS 11.0, *) {
self.navigationBar.prefersLargeTitles = true
self.navigationItem.largeTitleDisplayMode = .automatic
self.navigationBar.largeTitleTextAttributes = [NSForegroundColorAttributeName: UIColor.white]
self.navigationBar.barTintColor = UIColor(red:1, green:1, blue:1, alpha:1)
}
else {
self.navigationBar.setBackgroundImage(#imageLiteral(resourceName: "navigationBarBackground"), for: .default)
}
self.navigationBar.shadowImage = #imageLiteral(resourceName: "navigationBarShadow")
self.navigationBar.isTranslucent = false
}
}
Versuchen Sie diesen Code (Swift 4.0):
in viewDidLoad ()
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.black]
if #available(iOS 11.0, *) {
self.navigationController?.navigationBar.prefersLargeTitles = true
self.navigationItem.largeTitleDisplayMode = .automatic
self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.black]
} else {
//iOS <11.0
}
self.title = "Title"
self.navigationController?.navigationBar.barTintColor = UIColor(patternImage: #imageLiteral(resourceName: "nav_bg"))
self.navigationController?.navigationBar.isTranslucent = false
In Xamarin wäre es so:
this.NavigationBar.BackgroundColor = UIColor.Clear;
var gradientLayer = new CAGradientLayer
{
Frame = new CGRect(0, 0, UIApplication.SharedApplication.StatusBarFrame.Width,
UIApplication.SharedApplication.StatusBarFrame.Height + this.NavigationBar.Frame.Height),
Colors = new CGColor[]
{Constants.Defaults.Navigation.RealBlueColor.ToCGColor(), Constants.Defaults.Navigation.RealBlueColor.ToCGColor()}
};
UIGraphics.BeginImageContext(gradientLayer.Bounds.Size);
gradientLayer.RenderInContext((UIGraphics.GetCurrentContext()));
UIImage image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
this.View.Layer.InsertSublayer(gradientLayer, 0);
this.NavigationBar.BarTintColor = UIColor.FromPatternImage(image);
Das this.View.Layer.Insert ist optional. Ich brauche es, wenn ich ein Bild auf der Navigationsleiste auf und ab rolle
Das Ändern der Taktart hat für mich nicht funktioniert, also ändere ich die Ebene in der Navigationsleiste
navigationBar.layer.backgroundColor = UIColor(patternImage:
UIImage(named: "BG-Roof1")!.resizableImage(withCapInsets:
UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0), resizingMode: .stretch)).cgColor
Huckepack auf die Antwort von oldrinmendez - diese Lösung eignet sich perfekt für einen horizontalen Farbverlauf.
Für einen VERTICAL-Farbverlauf konnte ich dieselbe Funktion aus der Antwort von oldrinmendez verwenden, indem ich ihn erneut in scrollViewDidScroll aufrief. Dadurch wird die Höhe des Verlaufsbildes beim Scrollen des Benutzers kontinuierlich angepasst.
Beginne mit der Funktion von oldrinmendez:
func imageWithGradient(startColor:UIColor, endColor:UIColor, size:CGSize, horizontally:Bool) -> UIImage? {
let gradientLayer = CAGradientLayer()
gradientLayer.frame = CGRect(x: 0, y: 0, width: size.width, height: size.height)
gradientLayer.colors = [startColor.cgColor, endColor.cgColor]
if horizontally {
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
} else {
gradientLayer.startPoint = CGPoint(x: 0.5, y: 0)
gradientLayer.endPoint = CGPoint(x: 0.5, y: 1)
}
UIGraphicsBeginImageContext(gradientLayer.bounds.size)
gradientLayer.render(in: UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
Erstellen Sie eine Aktualisierungsfunktion, um sie mit den gewünschten Optionen aufzurufen:
func updateImageWithGradient() {
let navBarHeight = self.navigationController?.navigationBar.frame.size.height
let statusBarHeight = UIApplication.shared.statusBarFrame.height
let heightAdjustment: CGFloat = 2
let gradientHeight = navBarHeight! + statusBarHeight + heightAdjustment
let bgimage = imageWithGradient(startColor: UIColor.red, endColor: UIColor.orange, size: CGSize(width: UIScreen.main.bounds.size.width, height: gradientHeight), horizontally: false)
navigationController?.navigationBar.barTintColor = UIColor(patternImage: bgimage!)
}
Schließlich fügen Sie die Aktualisierungsfunktion zu scrollViewDidScroll & ViewDidApper hinzu: ViewDidAppear verwenden, damit die korrekte Navigationsleistenhöhe zurückgegeben wird
override func viewDidAppear(_ animated: Bool) {
updateImageWithGradient()
}
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
DispatchQueue.main.async {
updateImageWithGradient()
}
}