自定义背景图像与iOS 11中的大标题NavigationBar

你如何为iOS 11中的大标题NavigationBar设置自定义背景图片? 我正在使用我已经分配给故事板中的navigationControllers的自定义子类。

这是我如何创build我的自定义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") } } 

奇怪的是setBackgroundImage(image, for: .default)不适用于大标题。 它在iOS 10之前工作过,如果我旋转iPhone(并激活小NavBar)的背景是回来?

编辑: backgroundImage仍然呈现,但不知何故隐藏。 只有当你开始滚动和“正常”的导航栏出现时,backgroundImage是可见的。 在这种情况下barTintColor也完全被忽略。 截图 GIF

我有同样的问题,修复了

删除setBackgroundImage并使用barTint颜色与图案图像

 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!) 

用渐变色获取图像

 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 } 

在iOS 11中,如果使用大标题,则不需要设置BackgroundImage(删除其声明)。 相反,你需要使用BarTintColor。

 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 } } 

Xamarin会是这样的:

 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); 

this.View.Layer.Insert是可选的。 当我在NavigationBar上“下滑”一个图像时,我需要它