从“后退”按钮中删除文本,保留图标


92

我想从“后退”按钮中删除文本,但我想保留该图标。我努力了

let backButton = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.Plain, target: navigationController, action: nil)
navigationItem.leftBarButtonItem = backButton

但是,这将完全删除文本和图标。

Answers:


98

@ rmd2的方法几乎是正确的,但是您应该选择后退按钮指向的控制器的导航栏,然后" "在“后退按钮”字段中键入。

在此处输入图片说明


1
最坏的方法是,如果视图控制器没有导航栏,我将不得不添加删除文本
Daniel Beltrami

142

我知道这已经有了答案,但是您也可以通过代码来完成(以防您正在使用笔尖)

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

将以上内容添加到第一个视图控制器中。

请注意,您需要对要推送的每个视图控制器执行此操作。因此,如果您有3个视图控制器,并且要从所有视图控制器中删除背景文本,则必须在视图控制器1和2中添加该行。


5
到目前为止,这是我所见过的最好的解决方案,这丝毫没有给我带来麻烦
lostAtSeaJoshua

4
.Plain已更改为.plain。没有大写p。
Gal

完善..!这是我想要的。
京东。

最佳解决方案。谢谢。
巴兰·埃姆雷

1
@GastónAntonioMontes,它的工作对iOS13,但它是一个有点直觉:空标题backBarButtonItem应该上宣布视图控制器,而不是一个
马丁

49

经过大量搜索后,我发现了最佳,简单的解决方案,这将影响所有用Swift 4.2编写并在Swift 5中运行的viewControllers

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

欢迎使用@ e.dimitrow
iOS Lifee

1
作品如魅力
Jerry Okafor

3
请注意,如果您的视图控制器包含在故事板或笔尖......这只会工作
纳撒尼尔·布鲁默

1
一个天才的解决方案!
WM

3
这曾经对我有用,但不再起作用(它仍然可以在iOS 12模拟器上使用,但不能在最新的iOS 13上使用)...
tanya,

35

后退按钮的文本取决于主视图的标题。

技巧是在主视图消失时清除标题,并在再次显示时重新设置标题:

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    // needed to clear the text in the back navigation:
    self.navigationItem.title = " "
}

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

33

如果你想从一个推视图控制器删除后退按钮的标题,比方说<Settings<在subSettingsViewController,那么你已经设置backBarButtonItem冠军SettingsViewController的viewWillDisappear()方法。

目标C:

- (void)viewWillDisappear:(BOOL)animated
    [super viewWillDisappear:animated];
    self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:self.navigationItem.backBarButtonItem.style target:nil action:nil];
}

迅速:

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

1
.Plain已更改为.plain。没有大写p。
Gal

1
答案需要针对searchController行为进行更新。例如,如果您使用单独的resultsVC并点击推送另一个VC的项目,则不会调用初始searchController的viewWillDisappear方法,因此标题仍然存在
H4Hugo

如果您正在为整个应用程序中的屏幕寻找解决方案,那么这不是一个好方法。-如果将此代码添加到“基本视图控制器”中,则第二个视图控制器(通常在其中设置标题)的viewDidAppear之后将调用第一个视图控制器的viewWillDisappear ...这将使标题混乱。最好的方法是覆盖后退按钮
Mithra Singam '18

完美的解决方案谢谢
SURESH SANKE '18

28

如果要返回箭头,则将以下代码放入AppDelegate文件中,并放入didFinishLaunchingWithOptions方法中。

对于斯威夫特

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

2
我喜欢这一点,因为您可以在一个文件中标准化应用程序的样式,然后从应用程序委托中调用它一次
Aaronium112,18年

4
这确实是一个很好且快速的解决方案,但是...如果您还有其他条形按钮除外,那可能会很棘手
:)

3
一种观察,如果仅实现“ .normal”属性,则单击时将看到文本。为“ .selected”,“。highlighted”和“ .disabled”添加同一行。以确保您看不到闪烁的文本。
尼克N

1
我认为这会产生副作用,除后退按钮外,其他条形按钮也将受到影响,并具有清晰的文本颜色:(
dhin

23

就我而言,对于自定义图标和标题,这确实很有用(Swift 4)

    let imgBack = UIImage(named: "ic_back")

    navigationController?.navigationBar.backIndicatorImage = imgBack
    navigationController?.navigationBar.backIndicatorTransitionMaskImage = imgBack

    navigationItem.leftItemsSupplementBackButton = true
    navigationController?.navigationBar.topItem?.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: self, action: nil)

1
该代码的最后一行对我来说是完美的。所有其他建议均不起作用,可能是因为我的视图控制器全部由导航控制器控制。在这种情况下,navigationController是什么?确实是必需的。
Salx

如果要添加自定义后退按钮,则需要前四行。否则,最后一行将解决问题。
拉菲库尔·哈桑

14

我通过在以前的ViewController的StoryBoard标题上添加“”来解决此问题。只是一个空间,不是空的; D

在此处输入图片说明


我需要在前一个屏幕上显示标题,所以我想这对我不起作用。
lmiguelvargasf 2015年

2
我已经将该标题留空了,但标题仍在后退按钮标题中
Himali Shah

1
不要空白标题字段,在“后退按钮”字段中放置“”(空格)
Kiril S.

13

终于找到了完美的解决方案。

只需添加一个透明图像,然后在AppDelegate中添加以下代码即可。

UIBarButtonItem.appearance().setBackButtonBackgroundImage(#imageLiteral(resourceName: "transparent"), for: .normal, barMetrics: .default)

1
这绝对是最好的答案。我以前使用的是UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment大多数其他答案所建议的技巧,但是对于带有长标题的视图控制器,它在iPhone X上已损坏。该解决方案完美无缺。
Ned '18年

3
最佳答案。比透明文字颜色效果更好。
威廉·T。,

1
过去四年来我使用的最佳解决方案!您只需在一个地方为所有ViewController进行一次操作!!!
korgx9 '18

1
当我在iOS 12上尝试此操作时,文本仍显示在图像旁边。:(
肖恩·麦克梅因斯

13

迅速4

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

谢谢,它帮助了我(Swift 4.0,Xcode 10.1,iOS 12.1.1),谢谢
infinity_coding7

3
但你会失去你的标题在父母VC
微露

1
如果存在大标题,则topItem为largeTitle。不起作用
Saranjith

10

对于Swift 4+, 将这些行AppDelegate放在didFinishLaunchingWithOptions

let BarButtonItemAppearance = UIBarButtonItem.appearance()

BarButtonItemAppearance.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.clear], for: .normal)      
BarButtonItemAppearance.setBackButtonTitlePositionAdjustment(UIOffsetMake(-200, 0), for:UIBarMetrics.default)

当您在应用程序委托中设置外观时,每个UIBarButtonItem的前景色都是透明的,不是吗?因此,如果我添加带有文本的UIBarButtonItem,是否必须手动更改此按钮的前景色?
库兹杜

1
这很好,但是当您按下“后退”按钮时,它仍然显示文本
William T.

它可以工作,但可以使其他bar按钮在iOS 11中消失。上面Rafiqul Hasan的回答可以解决问题
huync

8

这对我有用

override func viewDidLoad() {
    super.viewDidLoad()
    navigationController?.navigationBar.topItem?.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}

纠正一个。在iOS 13中,navigationItem.backBarButtonItem不起作用。它节省了我的时间。谢谢
Manish

5

如果您有ViewControllerA,并且要导航到ViewControllerB,请在ViewControllerA中将当前的NavigationItem设置为新的UIBarButtonItem,并将标题设置为带有空格的字符串,然后再推送至另一个视图控制器:

将标题设置为带有空格的字符串,您不能设置nil或“”(空字符串),因为默认值为nil

let backItem = UIBarButtonItem()
backItem.title = " "
navigationItem.backBarButtonItem = backItem
let controllerB = ViewControllerB()
navigationController?.pushViewController(controllerB, animated: true)

5

将此代码放在每个VC中,这将推另一个

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

3
let button: UIButton = UIButton (type: UIButtonType.Custom)
button.setImage(UIImage(named: "imageName"), forState: UIControlState.Normal)
button.addTarget(self, action: "backButtonPressed:", forControlEvents: UIControlEvents.TouchUpInside)
button.frame = CGRectMake(0, 0, 30, 30)
let barButton = UIBarButtonItem(customView: button)

self.navigationItem.leftBarButtonItem = barButton

func backButtonPressed(btn : UIButton) {

    // Your code
}

3

要从导航控制器堆栈中的所有viewcontroller中删除:

子类化UINavigationController并添加以下内容:

override func show(_ vc: UIViewController, sender: Any?) {
    setEmptyBackButton(vc)
    super.show(vc, sender: sender)
}

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

func setEmptyBackButton(_ viewController: UIViewController) {
    viewController.navigationItem.backBarButtonItem =
        UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}

2

有时,如果标题很长,仅更改标题颜色是行不通的。因为它可能会将导航栏标题移到左侧。因此,为防止出现这种情况,除了使其透明之外,您可能还需要水平移动条形按钮的标题:

let barButtonItemAppearance = UIBarButtonItem.appearance()
    barButtonItemAppearance.setTitleTextAttributes([NSAttributedStringKey.foregroundColor: UIColor.clear], for: .normal)
    barButtonItemAppearance.setBackButtonTitlePositionAdjustment(UIOffsetMake(-200, 0), for:UIBarMetrics.default)

1

对我来说,这就是窍门:

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

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.navigationItem.title = "my amazing title"
    navigationItem.backBarButtonItem = UIBarButtonItem(title: " ", style: .plain, target: nil, action: nil)
}

请注意,如果仅设置标题而不修改 backBarButtonItem,它将似乎起作用。但是,如果您尝试使用手势返回,而不是取消并停留在推送的视图控制器上,则返回标题将返回。

Swift 4中工作


你能解释一下吗?
mrc

我有控制器,总是显示带有“后退”按钮的“后退”文本。所以以上代码对我而言不起作用
Shahbaz Akram

1

您应该选择控制器的导航栏,后退按钮将指向该导航栏,然后在“后退按钮”字段中键入“”。

例如,如果您要将A控制器推到B控制器,请将空格放在A控制器导航栏中。



1

细节

  • Xcode版本10.2.1(10E1001),Swift 5

1.创建UINavigationController的自定义类

import UIKit

class NavigationController: UINavigationController {
    override func viewDidLoad() {
        super.viewDidLoad()
        delegate = self
    }
}

extension NavigationController: UINavigationControllerDelegate {
    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        if viewController.navigationItemBackButtonTextIsHidden {
            viewController.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
        }
    }
}

2.添加UIViewController扩展

import UIKit

extension UIViewController {
    @objc var navigationItemBackButtonTextIsHidden: Bool { return false }
}

3.更新您的ViewController类

import UIKit

class ViewController: UIViewController {
    override var navigationItemBackButtonTextIsHidden: Bool { return true }
}

完整样本

import UIKit

// MARK: - ViewController

class ViewController: UIViewController {

    var screenCounter = 1

    override func viewDidLoad() {
        super.viewDidLoad()
        setupNavigationItem()
    }

    override var navigationItemBackButtonTextIsHidden: Bool { return (screenCounter % 2) == 0 }
}

extension ViewController {

    private func setupNavigationItem() {
        navigationItem.title = "VC \(screenCounter)"
        navigationItem.rightBarButtonItem = UIBarButtonItem(title: "push", style: .plain, target: self, action: #selector(pushBarButtonTouchedUpInside))
    }

    @objc func pushBarButtonTouchedUpInside(button: UIBarButtonItem) {
        guard let navigationController = navigationController else { return }
        let viewController = ViewController()
        viewController.screenCounter = screenCounter + 1
        viewController.view.backgroundColor = .white
        navigationController.pushViewController(viewController, animated: true)
    }
}

// MARK: - NavigationController

class NavigationController: UINavigationController {
    override func viewDidLoad() {
        super.viewDidLoad()
        delegate = self
    }
}

extension NavigationController: UINavigationControllerDelegate {
    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        if viewController.navigationItemBackButtonTextIsHidden {
            viewController.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
        }
    }
}

// MARK: - UIViewController extension

extension UIViewController {
    @objc var navigationItemBackButtonTextIsHidden: Bool { return false }
}

结果

在此处输入图片说明


1

一种替代覆盖所有ViewControllers对我来说是扩展UINavigationController和设置backBarButtonItemtopViewController

Swift 5 在Xcode 11.2.1上:

extension UINavigationController {
    override open func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        let backButton = UIBarButtonItem(title: " ", style: .plain, target: nil, action: nil)
        self.topViewController?.navigationItem.backBarButtonItem = backButton
    }
}

1

以编程方式执行此操作的最简单方法是backBarButtonItem从父视图控制器(调用push的控制器)进行设置。

class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

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

此处有更多详细信息https://sarunw.com/posts/how-to-remove-text-from-uinavigationbar-back-button/


1

您可以使用的委托方法从“后退”按钮删除文本UINavigationController

class CustomNavigationController: UINavigationController {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.delegate = self
    }

}

extension CustomNavigationController: UINavigationControllerDelegate {
    
    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        viewController.navigationItem.backBarButtonItem = UIBarButtonItem(title: String(), style: .plain, target: nil, action: nil)
    }
    
}

0

在带有Swift的Xcode 9.2中,它的工作方式如下:

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

0

对于我们无法完全控制以前的视图控制器的情况(即,如果我们在框架中工作),我们可以按以下方式删除后退按钮的标题:

// For iOS 10
navigationController?.navigationBar.items?.last?.backBarButtonItem?.title = String()

// For iOS 11
navigationController?.navigationBar.items?.last?.backBarButtonItem?.title = nil

它的作用是导航到导航堆栈的最后一项并删除其后标题。当我们的视图控制器出现时,请确保保存原始的:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    originalBackButtonTitle = navigationController?.navigationBar.items?.last?.backBarButtonItem?.title
    // Delete title somewhere here...
}

然后重新分配它,以免破坏应用程序的任何部分:

override func viewWillDisappear(_ animated: Bool) {
    navigationController?.navigationBar.items?.last?.backBarButtonItem?.title = originalBackButtonTitle
    super.viewWillDisappear(animated)
}

0

这将解决您的问题:

    import UIKit

    extension UINavigationController{

    func customizeBackArrow(){
        let yourBackImage = UIImage(named: "icon_back_arrow")
        self.navigationBar.backIndicatorImage = yourBackImage
        self.navigationBar.tintColor = Common.offBlackColor
        self.navigationBar.backIndicatorTransitionMaskImage = yourBackImage
        navigationItem.leftItemsSupplementBackButton = true
        self.navigationBar.topItem?.backBarButtonItem = UIBarButtonItem(title: "", 
           style: .plain, target: self, action: nil)

    }
}

0

我已经尝试了几个答案,但无法在所有情况下都能使它们起作用。因此,这是一种不影响导航栏标题(如果已设置)的解决方法。

    guard let items = viewController.navigationController?.navigationBar.items else { return }
    for item in items {
        if item.title == nil {
            item.title = ""
        }
    }

0

一种简单的编程方式(没有副作用)是在控制器的aakeakeFromNib方法(您要从中导航的方法)的aakeakeFromNib方法中用一个空项目初始化navigationItem.backBarButtonItem

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

注意:如果稍后像在viewDidLoad()方法中那样初始化后退按钮,则会失去后退功能(从左边缘向右滑动会使您在导航堆栈中后退一步)。

然后,如果要为不同的目标控制器使用不同的后退按钮文本,并且使用的是segues,则可以在prepare(for segue :, sender :)方法中设置标题,如下所示:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if let item = navigationItem.backBarButtonItem {
        switch segue.identifier {
        case "SceneOne": item.title = "Back"; break
        case "SceneTwo": item.title = "Home"; break
        case "SceneThree": item.title = nil; break // Use this scene's title
        default: item.title = "" // No text
        }
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.