简体   繁体   English

更改导航栏底部边框颜色 Swift

[英]Change navigation bar bottom border color Swift

It works with它与

import UIKit

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    self.navigationController?.navigationBar.setBackgroundImage(UIImage(), forBarMetrics: .Default)
    self.navigationController?.navigationBar.shadowImage = UIColor.redColor().as1ptImage()


}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


}

extension UIColor {
    func as1ptImage() -> UIImage {
        UIGraphicsBeginImageContext(CGSizeMake(1, 1))
        let ctx = UIGraphicsGetCurrentContext()
        self.setFill()
        CGContextFillRect(ctx, CGRect(x: 0, y: 0, width: 1, height: 1))
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}

But when I add a UITableView it doesn't appear on it and when I add a UISearchView it appears but removes the navigation bar.但是当我添加一个 UITableView 它不会出现在它上面,当我添加一个 UISearchView 它会出现但删除导航栏。

Anyone knows how to solve this?有谁知道如何解决这个问题?

You have to adjust the shadowImage property of the navigation bar.您必须调整导航栏的shadowImage属性。

Try this one.试试这个。 I created a category on UIColor as an helper, but you can refactor the way you prefer.我在 UIColor 上创建了一个类别作为助手,但您可以按照自己喜欢的方式重构。

extension UIColor {
    func as1ptImage() -> UIImage {
        UIGraphicsBeginImageContext(CGSizeMake(1, 1))
        let ctx = UIGraphicsGetCurrentContext()
        self.setFill()
        CGContextFillRect(ctx, CGRect(x: 0, y: 0, width: 1, height: 1))
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return image
    }
}

Option 1: on a single navigation bar选项 1:在单个导航栏上

And then in your view controller (change the UIColor to what you like):然后在您的视图控制器中(将 UIColor 更改为您喜欢的颜色):

// We can use a 1px image with the color we want for the shadow image
self.navigationController?.navigationBar.shadowImage = UIColor.redColor().as1ptImage()

// We need to replace the navigation bar's background image as well 
// in order to make the shadowImage appear. We use the same 1px color tecnique
self.navigationController?.navigationBar.setBackgroundImage(UIColor.yellowColor‌​().as1ptImage(), forBarMetrics: .Default)    

Option 2: using appearance proxy, on all navigation bars选项 2:在所有导航栏上使用外观代理

Instead of setting the background image and shadow image on each navigation bar, it is possible to rely on UIAppearance proxy.而不是在每个导航栏上设置背景图像和阴影图像,可以依赖 UIAppearance 代理。 You could try to add those lines to your AppDelegate, instead of adding the previous ones in the viewDidLoad.您可以尝试将这些行添加到您的 AppDelegate,而不是在 viewDidLoad 中添加以前的行。

// We can use a 1px image with the color we want for the shadow image
UINavigationBar.appearance().shadowImage = UIColor.redColor().as1ptImage()

// We need to replace the navigation bar's background image as well 
// in order to make the shadowImage appear. We use the same 1px color technique
UINavigationBar.appearance().setBackgroundImage(UIColor.yellowColor().as1ptImage(), forBarMetrics: .Default)

Wonderful contributions from @TheoF, @Alessandro and @Pavel. @TheoF、@Alessandro 和 @Pavel 的精彩贡献。

Here is what I did for...这是我为...

Swift 4斯威夫特 4

extension UIColor {

    /// Converts this `UIColor` instance to a 1x1 `UIImage` instance and returns it.
    ///
    /// - Returns: `self` as a 1x1 `UIImage`.
    func as1ptImage() -> UIImage {
        UIGraphicsBeginImageContext(CGSize(width: 1, height: 1))
        setFill()
        UIGraphicsGetCurrentContext()?.fill(CGRect(x: 0, y: 0, width: 1, height: 1))
        let image = UIGraphicsGetImageFromCurrentImageContext() ?? UIImage()
        UIGraphicsEndImageContext()
        return image
    }
}

Using it in viewDidLoad() :viewDidLoad()使用它:

/* In this example, I have a ViewController embedded in a NavigationController in IB. */

// Remove the background color.
navigationController?.navigationBar.setBackgroundImage(UIColor.clear.as1ptImage(), for: .default)

// Set the shadow color.
navigationController?.navigationBar.shadowImage = UIColor.gray.as1ptImage()

Putting @alessandro-orru's answer in one extension将@alessandro-orru 的答案放在一个扩展中

extension UINavigationController {

    func setNavigationBarBorderColor(_ color:UIColor) {
        self.navigationBar.shadowImage = color.as1ptImage()
    }
}

extension UIColor {

    /// Converts this `UIColor` instance to a 1x1 `UIImage` instance and returns it.
    ///
    /// - Returns: `self` as a 1x1 `UIImage`.
    func as1ptImage() -> UIImage {
        UIGraphicsBeginImageContext(CGSize(width: 1, height: 1))
        setFill()
        UIGraphicsGetCurrentContext()?.fill(CGRect(x: 0, y: 0, width: 1, height: 1))
        let image = UIGraphicsGetImageFromCurrentImageContext() ?? UIImage()
        UIGraphicsEndImageContext()
        return image
    }
}

then in your view controller just add:然后在您的视图控制器中添加:

self.navigationController?.setNavigationBarBorderColor(UIColor.red)

Solution for Swift 4.0 - 5.2 Swift 4.0 - 5.2 的解决方案

Here is small extension for changing both Height and Color of bottom navbar line这是用于更改底部导航栏线的高度和颜色的小扩展

extension UINavigationController
{
    func addCustomBottomLine(color:UIColor,height:Double)
    {
        //Hiding Default Line and Shadow
        navigationBar.setValue(true, forKey: "hidesShadow")
    
        //Creating New line
        let lineView = UIView(frame: CGRect(x: 0, y: 0, width:0, height: height))
        lineView.backgroundColor = color
        navigationBar.addSubview(lineView)
    
        lineView.translatesAutoresizingMaskIntoConstraints = false
        lineView.widthAnchor.constraint(equalTo: navigationBar.widthAnchor).isActive = true
        lineView.heightAnchor.constraint(equalToConstant: CGFloat(height)).isActive = true
        lineView.centerXAnchor.constraint(equalTo: navigationBar.centerXAnchor).isActive = true
        lineView.topAnchor.constraint(equalTo: navigationBar.bottomAnchor).isActive = true
    }
}

And after adding this extension, you can call this method on any UINavigationController (eg from ViewController viewDidLoad() )添加此扩展后,您可以在任何 UINavigationController 上调用此方法(例如从 ViewController viewDidLoad()

self.navigationController?.addCustomBottomLine(color: UIColor.black, height: 20)

这些天有一个更好的选择:

UINavigationBar.appearance().shadowImage = UIImage()

for Swift 3.0 just change this line:对于Swift 3.0,只需更改这一行:

CGContextFillRect(ctx, CGRect(x: 0, y: 0, width: 1, height: 1))

to this:对此:

ctx?.fill(CGRect(x: 0, y: 0, width: 1, height: 1))

From iOS 13 on, you can use the UINavigationBarAppearance() class with the shadowColor property:从 iOS 13 开始,您可以使用带有shadowColor属性的UINavigationBarAppearance()类:

if #available(iOS 13.0, *) {
  let style = UINavigationBarAppearance()
  style.shadowColor = UIColor.clear // Effectively removes the border
  navigationController?.navigationBar.standardAppearance = style

  // Optional info for follow-ups:
  // The above will override other navigation bar properties so you may have to assign them here, for example:
  //style.buttonAppearance.normal.titleTextAttributes = [.font: UIFont(name: "YourFontName", size: 17)!]
  //style.backgroundColor = UIColor.orange
  //style.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white,
                               NSAttributedString.Key.font: UIFont(name: "AnotherFontName", size: 20.0)!]
} else {
  // Fallback on earlier versions
}

For iOS 13 and later适用于 iOS 13 及更高版本

    guard let navigationBar = navigationController?.navigationBar else { return }
    navigationBar.isTranslucent = true
    if #available(iOS 13.0, *) {
        let appearance = UINavigationBarAppearance()
        appearance.configureWithTransparentBackground()
        appearance.backgroundImage = UIImage()
        appearance.backgroundColor = .clear
        navigationBar.standardAppearance = appearance
    } else {
        navigationBar.setBackgroundImage(UIImage(), for: .default)
        navigationBar.shadowImage = UIImage()
    }

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

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