如何删除所有导航栏后退按钮标题

How to remove all navigationbar back button title

当我按下 UIViewController 时,它在新 UIViewController 的后退按钮中有一些标题,如果标题有很多文字,它在 iPhone 中看起来不太好4s 所以我要删除它

如果我在prepareForSegue函数中添加一些代码,那就麻烦了。

有什么更好的办法吗?

如果你想要后退箭头,那么下面的代码将 AppDelegate 文件放入 didFinishLaunchingWithOptions 方法。

For Objective-C

 [[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -60) forBarMetrics:UIBarMetricsDefault];

For Swift

let BarButtonItemAppearance = UIBarButtonItem.appearance()
BarButtonItemAppearance.setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.clear], for: .normal)

下面给出另一个选项。

Objective C

self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];

Swift

self.navigationItem.backBarButtonItem = UIBarButtonItem(title:"", style:.plain, target:nil, action:nil)

更新:

    let BarButtonItemAppearance = UIBarButtonItem.appearance()

    let attributes: [NSAttributedStringKey: Any] = [
    BarButtonItemAppearance.setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.clear], for: .normal)
            NSAttributedStringKey.font: UIFont.systemFont(ofSize: 0.1),
            NSAttributedStringKey.foregroundColor: UIColor.clear]

    BarButtonItemAppearance.setTitleTextAttributes(attributes, for: .normal)
    BarButtonItemAppearance.setTitleTextAttributes(attributes, for: .highlighted)

更新 SWIFT 4.1 :

    let attributes = [NSAttributedStringKey.font:  UIFont(name: "Helvetica-Bold", size: 0.1)!, NSAttributedStringKey.foregroundColor: UIColor.clear]

    BarButtonItemAppearance.setTitleTextAttributes(attributes, for: .normal)
    BarButtonItemAppearance.setTitleTextAttributes(attributes, for: .highlighted)

使用偏移量

UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(-1000, 0), for:UIBarMetrics.default)

我一般在UIViewController的viewDidLoad中添加或更改后退按钮。

类似的东西应该可以工作:

let leftButton = UIBarButtonItem(title: "Back", style:     UIBarButtonItemStyle.Plain, target: self, action: "closeView:")
self.navigationItem.leftBarButtonItem = leftButton

不要忘记更改并实现关闭视图时调用的函数。

更简单,只需更改标题:

self.navigationItem.leftBarButtonItem.title = "Back"

我在 AppDelegate 文件中使用这行代码到 didFinishLaunchingWithOptions 方法中删除后退按钮 title

Swift 2.x

let barAppearace = UIBarButtonItem.appearance()
barAppearace.setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -60), forBarMetrics:UIBarMetrics.Default)

Swift 3.x

UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -60), for:UIBarMetrics.default)

Swift 4.x

UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.clear], for: .normal)
    UIBarButtonItem.appearance().setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.clear], for: UIControlState.highlighted)

我对 setBackButtonTitlePositionAdjustment 解决方案不满意,所以这里有一个 swift 替代方案来隐藏整个应用程序中的所有后退按钮文本:

    UIBarButtonItem.appearance().setTitleTextAttributes([NSFontAttributeName: barbuttonFont, NSForegroundColorAttributeName:UIColor.clearColor()], forState: UIControlState.Normal)
    UIBarButtonItem.appearance().setTitleTextAttributes([NSFontAttributeName: barbuttonFont, NSForegroundColorAttributeName:UIColor.clearColor()], forState: UIControlState.Highlighted)

您必须从 didFinishLaunchingWithOptions 函数中的 AppDelegate 调用它们。

外观也必须设置为 .Highlighted 状态,以避免在用户点击后退按钮时显示文本。

您可以使用 xcode 8 和 swift 3.0

self.navigationController?.navigationBar.backItem?.title = " "

在 Swift 3

上工作就像魅力一样
self.navigationController?.navigationBar.topItem?.title = " "

Swift 3:

self.navigationItem.backBarButtonItem = UIBarButtonItem(title:"", style:.plain, target:nil, action:nil)
let barAppearace = UIBarButtonItem.appearance()
barAppearace.setBackButtonTitlePositionAdjustment(UIOffsetMake(0, -60), for:UIBarMetrics.default)

在swift3.0

中使用了这行代码

您可以为您想要此行为的所有 UIViewController 创建一个子类,并在子类的 viewDidLoad:

override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationItem.backBarButtonItem = UIBarButtonItem(
        title: "", style: .plain, target: nil, action: nil)
}

这样一来,您就可以选择您想要的控制器的行为,而无需重复代码。我更喜欢我的控制器只说 "Back",而不是以前控制器的标题,所以我在这里设置那个标题。

rordulu's answer here 中汲取灵感,我最终创建了一个自定义的 UINavigationController 和 UINavigation 栏,它们似乎可以处理这个棘手问题的所有情况。

1) 使用自定义 UINavigationBar:

初始化新的 UINavigationController
class CustomNavigationController: UINavigationController {

    convenience init() {
        self.init(navigationBarClass: CustomNavigationBar.self, toolbarClass: nil)
    }
}

2) 设置导航栏的backItem.title 属性为空字符串,每次视图自己布局时

class CustomNavigationBar: UINavigationBar {

    override func layoutSubviews() {
        backItem?.title = ""
        super.layoutSubviews()
    }
}

现在每次使用这个导航控制器和栏组合时,它永远不会有后退按钮文本!

注意:如果还使用故事板,这应该可以正常工作,只需确保将自定义导航栏组件放入视图中

只需转到您的 Parent ViewController 从其他 ViewController 依赖的地方。

override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(true)
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)}

我不知道为什么,但我发现在 iPhone 加号中隐藏后退按钮标题有问题,但在没有加号的设备中显示正确

leftBarButtonItem.title = ""

所以我找到了简单的方法。它在自动布局中的 NavigationViewController 的 NavigationBar 中将色调颜色设置为清除。如果您使用带有色调的图标或文本块,则可能会出现问题。但就我而言,我并没有完全使用它。

很简单。在后退按钮的标题中放置一个 space 并准备就绪。 请记住,它必须在您要删除文本的上一个视图中。

只需使用这个:

func removeBackButton(vc:UIViewController) {
        let button = UIButton.init(type: .custom)
        button.setImage(UIImage.init(named:""), for: .normal)
        let leftBarButton = UIBarButtonItem.init(customView: button)
        vc.navigationItem.leftBarButtonItem = leftBarButton
}

所以在viewDidLoad中调用这个方法:

override func viewDidLoad() {
        super.viewDidLoad()
     removeBackButton(vc:self)
}

在这里添加第二个答案,因为我的第一个答案只部分起作用。这种方法不太优雅,因为它需要在应用程序的每个视图中调用一个方法,但是它可以在没有任何 side-effects.

的情况下工作

因此,首先,创建一个 UIViewController 扩展 class,其中包含删除后退按钮文本并添加自定义后退按钮的功能:

extension UIViewController {

func setBackButton() {
    navigationController?.navigationBar.backIndicatorImage = R.image.backArrow()
    navigationController?.navigationBar.backIndicatorTransitionMaskImage = R.image.backArrow()
    navigationItem.backBarButtonItem = UIBarButtonItem(title: " ", style: .plain, target: nil, action: nil)
}

其次,我们可以简单地在您需要的每个视图控制器的 viewDidLoad 中调用此函数。

您可以将此扩展添加到 UIViewController 然后在每个 viewDidLoad() 中调用这个函数 喜欢:self.updateBackButton()

extension UIViewController {
func updateBackButton(){
    if self.navigationController != nil {
        self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .done, target: self, action: nil)
    }
}}

只需将此代码复制到 didFinishLaunchingWithOptions launchOptions

Swift 5

UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffset(horizontal: -1000.0, vertical: 0.0), for: .default)

Swift 4

UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(-1000.0, 0.0), for: .default)

简单的解决方案:

当您从第一个控制器推动第二个控制器时,将 self.navigationItem.title = "" 放在第一个控制器的 viewWillDisappear 中。它隐藏了第二个控制器的后退按钮标题。

以上声明隐藏了第一个控制器的标题,因此当我们回来时,我们再次想要第一个控制器的标题。为此,我们在第一个控制器的viewWillAppear方法中为第一个控制器添加标题

参考以下方法(第一个控制器)

    override func viewWillDisappear(_ animated: Bool) {
    self.navigationItem.title = ""
}

override func viewWillAppear(_ animated: Bool) {
    self.navigationItem.title = "Title"
}

Swift 4.2

UIBarButtonItem.appearance().setTitleTextAttributes([.foregroundColor: UIColor.clear], for: .normal)

我想分享一个适合我的解决方案。此外,它可以根据您的需要和要求进行调整。

请注意,在我的例子中,我使用故事板来指定 CustomNavigationBar

Swift 4.2

class CustomNavigationBar: UINavigationBar {

    override func awakeFromNib() {
        super.awakeFromNib()
        guard let topItem = topItem else { return }
        removeBackButtonTitle(for: topItem)
    }

    override func pushItem(_ item: UINavigationItem, animated: Bool) {
        removeBackButtonTitle(for: item)
        super.pushItem(item, animated: animated)
    }

    func removeBackButtonTitle(for item: UINavigationItem) {
        item.backBarButtonItem = UIBarButtonItem()
    }
}

Swift 4.2

的更新答案

使用 UIAppearance 是解决问题的一种更简洁的方法,但它会导致所有 UIBarButtonItem 都具有明文。解决方案的改进版本可能是检查 UIBarButtonItem 是否包含在 UINavigationBar 中。

    UIBarButtonItem.appearance(whenContainedInInstancesOf: [UINavigationBar.self]).setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.clear], for: .normal)

适用于 Swift 4.2

使用 AppDelegate 文件中的代码行到 didFinishLaunchingWithOptions

    UIBarButtonItem.appearance(whenContainedInInstancesOf: [UINavigationBar.self]).setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.clear], for: .normal)

    UIBarButtonItem.appearance(whenContainedInInstancesOf: [UINavigationBar.self]).setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.clear], for: .highlighted)

Swift 4.2 & 5

不要使用导航栏色调,如果您稍后在代码中随时使用图像选择器,这会产生副作用。

使用以下代码:

extension UIViewController {
        open override func awakeFromNib() {
            navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    }  
}

从您的第一个 ViewController 调用它:

self.awakeFromNib()

对于swift 4,5

let BarButtonItemAppearance = UIBarButtonItem.appearance()
BarButtonItemAppearance.setTitleTextAttributes([NSForegroundColorAttributeName: UIColor.clear], for: .normal)

只需使用覆盖函数 awakeFromNib() 创建 UIViewController 的扩展,并使用空标题制作 UIBarButtonItem 并提供给 navigation backBarButtonItem

extension UIViewController {

  open override func awakeFromNib() {
    let backBarBtnItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    navigationItem.backBarButtonItem = backBarBtnItem
  }

}

将下面的代码放在任何 UIViewcontroller extension 中,它将隐藏所有 UIViewcontroller 返回文本

open override func awakeFromNib() {
        navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    }

适用于 Swift 5:

        self.navigationItem.backBarButtonItem?.title = ""

请注意,它将对下一个推送的视图控制器有效,而不是显示器上的当前视图控制器,这就是为什么它非常混乱!

此外,检查情节提要和 select previous 视图控制器的导航项,然后在 后退按钮 (检查员)。

对于那些不想在不同的视图控制器中使用方法混合或复制类似代码的人,我有一个简单的解决方案。

要删除后退按钮标题,请创建一个 UINavigationController 子类并覆盖 pushViewController(_, animated:) 方法:

final class CustomNavigationController: UINavigationController {

    override func pushViewController(_ viewController: UIViewController, animated: Bool) {

        super.pushViewController(viewController, animated: animated)

        let backBarButtonItem = UIBarButtonItem()
        backBarButtonItem.title = nil

        viewController.navigationItem.backBarButtonItem = backBarButtonItem
    }
}

viewDidLoad()

    let backBarButtonItem = UIBarButtonItem(title: nil, style: .plain, target: nil, action: nil)
    navigationItem.backBarButtonItem = backBarButtonItem

在 iOS 14 现在出现在 backButtonDisplayMode 属性 UINavigationItem class 中。因此,要删除后退按钮标题,您可以使用

navigationItem.backButtonDisplayMode = .minimal

在 viewController 的 viewDidLoad func 中你想删除它的地方。

为了在所有导航栏中删除它,我使用了 swizzling 技术

import UIKit

private let swizzling: (UIViewController.Type, Selector, Selector) -> Void = { forClass, originalSelector, swizzledSelector in
    if let originalMethod = class_getInstanceMethod(forClass, originalSelector), let swizzledMethod = class_getInstanceMethod(forClass, swizzledSelector) {
        let didAddMethod = class_addMethod(forClass, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))
        if didAddMethod {
            class_replaceMethod(forClass, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
        } else {
            method_exchangeImplementations(originalMethod, swizzledMethod)
        }
    }
}

extension UIViewController {
    
    static func swizzle() {
        let originalSelector1 = #selector(viewDidLoad)
        let swizzledSelector1 = #selector(swizzled_viewDidLoad)
        swizzling(UIViewController.self, originalSelector1, swizzledSelector1)
    }
    
    @objc open func swizzled_viewDidLoad() {
        if let _ = navigationController {
            if #available(iOS 14.0, *) {
                navigationItem.backButtonDisplayMode = .minimal
            } else {
                // Fallback on earlier versions
                navigationItem.backButtonTitle = ""
            }
        }
        swizzled_viewDidLoad()
    }
}

并在application(_:didFinishLaunchingWithOptions:)调用

UIViewController.swizzle()

iOS13 的方法。

let backButtonAppearance = UIBarButtonItemAppearance(style: .plain)
backButtonAppearance.normal.titleTextAttributes = [.foregroundColor: UIColor.clear]

let navigationBarAppearance = UINavigationBarAppearance()
navigationBarAppearance.backButtonAppearance = backButtonAppearance

UINavigationBar.appearance().standardAppearance = navigationBarAppearance
class NavigationController: UINavigationController {

    override func pushViewController(_ viewController: UIViewController, animated: Bool) {
        super.pushViewController(viewController, animated: animated)

        viewController.navigationItem.backButtonTitle = ""
    }
}

如果您想在打开下一个屏幕时删除后退按钮标题

在初始化和推送新屏幕的函数中执行此操作:

navigationItem.backButtonTitle = ""

完整用法:

    let view = SomeView()
    let controller = UIHostingController(rootView: view)
    navigationItem.backButtonTitle = ""
    navigationController?.pushViewController(controller, animated: true)

但要为应用中的所有导航栏自定义后退按钮,您需要执行以下操作:

func setupNavBarAppearance() {
    let backButtonImage = Images.west.image.withAlignmentRectInsets(UIEdgeInsets(top: -5, left: -15, bottom: -5, right: -15))
    let backButtonAppearance = UIBarButtonItemAppearance(style: .plain)
    backButtonAppearance.normal.titleTextAttributes = [.foregroundColor: UIColor.clear]
    
    let appearance = UINavigationBarAppearance()
    appearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.white]
    appearance.backButtonAppearance = backButtonAppearance
    appearance.setBackIndicatorImage(backButtonImage, transitionMaskImage: backButtonImage)
    
    UINavigationBar.appearance().standardAppearance = appearance
    UINavigationBar.appearance().scrollEdgeAppearance = appearance
    UINavigationBar.appearance().tintColor = .white
    UINavigationBar.appearance().isTranslucent = false
}

您可以从您的 AppDelegate.swift

调用它
    if #available(iOS 14.0, *) {
        navigationItem.backButtonDisplayMode = .minimal
    } else {
        navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    }