简体   繁体   English

从保留图标的后退按钮中删除文本

[英]Remove text from Back button keeping the icon

I want to remove the text from the back button, but I want to keep the icon.我想从后退按钮中删除文本,但我想保留图标。 I have tried我努力了

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

However, this removes completely the text and the icon.但是,这会完全删除文本和图标。

I know this already has an answer, but you can also do it in code (in case you're working with nibs)我知道这已经有了答案,但你也可以在代码中完成(如果你正在使用 nibs)

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

Add the above in the first view controller.在第一个视图控制器中添加上述内容。

Note that you need to do this for each view controller that is pushing.请注意,您需要为每个正在推送的视图控制器执行此操作。 So if you have 3 view controllers, and you want to remove the back text from all of them, you'll have to add the line in view controller 1 and 2.因此,如果您有 3 个视图控制器,并且想要从所有视图控制器中删除后面的文本,则必须在视图控制器 1 和 2 中添加该行。

The method of @rmd2 is almost right, but instead you should select the navigation bar of the controller to which back button will point to and type " " in the Back Button field. @rmd2 的方法几乎是正确的,但是您应该选择后退按钮将指向的控制器的导航栏,然后在后退按钮字段中键入" "

在此处输入图像描述

After Searching a lot I found best and simple solution, this will affect all the viewControllers written in Swift 4.2 and also working in Swift 5经过大量搜索后,我找到了最佳和简单的解决方案,这将影响所有用 Swift 4.2 编写的视图控制器,也可以在 Swift 5 中工作

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

After iOS 14 iOS 14 之后

extension UIViewController {
    open override func awakeAfter(using coder: NSCoder) -> Any? {
        navigationItem.backButtonDisplayMode = .minimal // This will help us to remove text
        return super.awakeAfter(using: coder)
    }
}

The text of the back button depends on the title of the master view.后退按钮的文本取决于主视图的标题。

The trick is to clear the title if the master view disappears and set it again if it is shown again:诀窍是在主视图消失时清除标题,如果再次显示则重新设置:

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

If you wanted to remove the title of a back button from a pushed view controller...如果您想从推送的视图控制器中删除后退按钮的标题...

let's say a class named SettingsVC is going to push SubSettingsVC then in the subSettingsVC back button will show a title <Settings so in order to remove the "settings" text from back button and make it something like <假设一个名为SettingsVC的类将推送 SubSettingsVC然后在 subSettingsVC 后退按钮中将显示一个标题<Settings所以为了从后退按钮中删除“设置”文本并使其类似于<

you've to set backBarButtonItem title in SettingsVC's viewWillDisappear() method.您必须在 SettingsVC 的viewWillDisappear()方法中设置backBarButtonItem标题。

Objective-C:目标-C:

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

Swift:迅速:

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

If you want back arrow so following code put into AppDelegate file into didFinishLaunchingWithOptions method.如果您想要返回箭头,请将以下代码放入 AppDelegate 文件中的 didFinishLaunchingWithOptions 方法中。

For Swift对于斯威夫特

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

In my case, for custom icon and title this did the trick (Swift 4)就我而言,对于自定义图标和标题,这可以解决问题(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)

This is working for me这对我有用

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

Finally found perfect solution.终于找到了完美的解决方案。

Just add one transparent Image and add following code in your AppDelegate.只需添加一个透明图像并在您的 AppDelegate 中添加以下代码。

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

I solved this problem by adding a " " on the StoryBoard Title of the previous ViewController.我通过在前一个 ViewController 的 StoryBoard Title 上添加一个“”来解决这个问题。 Just a space, not empty ;D只是一个空间,不是空的;D

在此处输入图像描述

在迅速 4

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

For Swift 4+ put these lines into AppDelegate at didFinishLaunchingWithOptions对于Swift 4+将这些行放入AppDelegatedidFinishLaunchingWithOptions

let BarButtonItemAppearance = UIBarButtonItem.appearance()

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

If you have a ViewControllerA and you want to navigate to the ViewControllerB, in the ViewControllerA, you should set the current navigationItem with a new UIBarButtonItem and the title to a string with blank space before push to another view controller:如果你有一个 ViewControllerA 并且你想导航到 ViewControllerB,在 ViewControllerA 中,你应该在推送到另一个视图控制器之前将当前的 navigationItem 设置为一个新的 UIBarButtonItem 并将标题设置为一个带有空格的字符串:

Set the title to a string with a blank space, you can't set nil or "" (empty string) because the default value is nil设置标题为带空格的字符串,不能设置 nil 或 ""(空字符串),因为默认值为 nil

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

将此代码放入每个 VC 中,该 VC 会推送另一个

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

You can remove text from back button using a delegate method of UINavigationController .您可以使用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)
    }
    
}
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
}

To remove from all viewcontrollers in a navigation controller stack:从导航控制器堆栈中的所有视图控制器中删除:

subclass UINavigationController and add this:子类 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)
}

Xcode 10, Swift 4+ Xcode 10,斯威夫特 4+

Similar answer to the others here but it is worth noting that if the text still isn't cleared, you have to click Space then Enter.此处与其他人的答案类似,但值得注意的是,如果文本仍未清除,则必须单击 Space 然后 Enter。

在此处输入图像描述

Sometimes its not working to change only the title color, in case when the title is long.有时,如果标题很长,仅更改标题颜色是行不通的。 Because it might shift the navigation bar title to the left.因为它可能会将导航栏标题向左移动。 So to prevent it you might need to shift the bar button title horizontally in addition to make it transparent:因此,为了防止它,您可能需要水平移动栏按钮标题以使其透明:

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

This will solve your issue:这将解决您的问题:

    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)

    }
}

Details细节

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

Solution解决方案

1. Create custom class of the UINavigationController 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. Add UIViewController extension 2.添加UIViewController扩展

import UIKit

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

3. Update your ViewController class 3. 更新你的 ViewController 类

import UIKit

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

Full sample完整样本

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

Result结果

在此处输入图像描述

Swift 5 Version remove back button title and set custom Image ios 13.0+ Swift 5 版本删除后退按钮标题并设置自定义图像 ios 13.0+

 let backButtonAppearance = UIBarButtonItemAppearance(style: .plain)
        backButtonAppearance.normal.titleTextAttributes = [.foregroundColor: UIColor.clear]
        let navigationBarAppearance = UINavigationBarAppearance()
        navigationBarAppearance.backButtonAppearance = backButtonAppearance
        navigationBarAppearance.setBackIndicatorImage(#imageLiteral(resourceName: "back"), transitionMaskImage: #imageLiteral(resourceName: "back"))
        UINavigationBar.appearance().standardAppearance = navigationBarAppearance

Add this code in App delegate didFinishLaucnh在 App 委托 didFinishLaucnh 中添加此代码

For me this did the trick:对我来说,这成功了:

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

Notice that if you only set the title without modifying the backBarButtonItem it will appear to work.请注意,如果您只设置标题而不修改backBarButtonItem,它似乎可以工作。 But if you try to go back using a gesture and than cancel and stay on the pushed view controller, the back title will come back.但是,如果您尝试使用手势返回而不是取消并停留在推送的视图控制器上,则返回标题将返回。

Working in Swift 4Swift 4中工作

You should select the navigation bar of the controller FROM which back button will point to and type " " in the Back Button field.您应该选择控制器的导航栏,从哪个后退按钮将指向并在后退按钮字段中键入“”。

eg if you are pushing A controller to B controller, put whitespace in A controller navigation bar.例如,如果您将 A 控制器推送到 B 控制器,请在 A 控制器导航栏中放置空格。

I've tried a couple of answers and I can't get them to work in all cases.我已经尝试了几个答案,但我无法让它们在所有情况下都能正常工作。 So this is a workaround to not affect the title of the navigation bar if it's set.因此,如果已设置,这是一种不影响导航栏标题的解决方法。

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

One alternative to override all ViewControllers for me was to extend UINavigationController and set the backBarButtonItem of the topViewController .对我来说覆盖所有ViewControllers的一种替代方法是扩展UINavigationController并设置backBarButtonItemtopViewController

Swift 5 on Xcode 11.2.1: Xcode 11.2.1 上的Swift 5

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

The easy programmatic way, without unwanted side-effects, is initializing the navigationItem.backBarButtonItem with an empty item in the awakeFromNib method of the source controller (the one you are navigating from):没有不必要的副作用的简单编程方法是在控制器的awakeFromNib方法(您从中导航的那个)中使用一个空项目初始化navigationItem.backBarButtonItem

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

Note: If you initialized the back button later, like in the viewDidLoad() method, than you would lose swipe-back functionality (swiping from the left edge to the right takes you one step back in the navigation stack).注意:如果您稍后初始化后退按钮,例如在viewDidLoad()方法中,那么您将失去向后滑动功能(从左边缘滑动到右侧会使您在导航堆栈中后退一步)。

Then, if you want different back button texts for different destination controllers and if you're using segues, you can set the title in the prepare(for segue:, sender:) method, like this:然后,如果你想为不同的目标控制器提供不同的后退按钮文本,并且如果你正在使用 segue,你可以在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
        }
    }
}

The easiest way to do this programmatically is to set backBarButtonItem from the parent view controller (a controller that calls push).以编程方式执行此操作的最简单方法是从父视图控制器(调用 push 的控制器)设置backBarButtonItem

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

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

More detail here https://sarunw.com/posts/how-to-remove-text-from-uinavigationbar-back-button/更多细节在这里https://sarunw.com/posts/how-to-remove-text-from-uinavigationbar-back-button/

In Xcode 9.2 with Swift, it worked like this:在带有 Swift 的 Xcode 9.2 中,它是这样工作的:

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

For the case where we have not control at all of the previous view controller (ie if we are working in a framework), we can delete the title of the back button as follow:对于我们完全没有控制之前的视图控制器的情况(即如果我们在框架中工作),我们可以删除后退按钮的标题,如下所示:

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

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

What it does is to navigate to the last item of the navigation's stack and delete its back title.它的作用是导航到导航堆栈的最后一项并删除其后面的标题。 Make sure to save the original one when our view controller will appear:当我们的视图控制器出现时,请确保保存原始的:

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

and then reassign it, in order to not disrupt any part of the app:然后重新分配它,以免破坏应用程序的任何部分:

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

After struggling a lot, the only thing that WORKDED for me was:在经历了很多挣扎之后,唯一对我有用的是:

  1. Click on your button no Storyboard/Xib点击你的按钮没有 Storyboard/Xib

  2. Since every button needs a name(even if you don't want to display it on the Ui), go to IdentityInspector[ Cmd + Option + 4 ] and on {Document-Label} write a name for it.由于每个按钮都需要一个名称(即使您不想在 Ui 上显示它),go 到 IdentityInspector[ Cmd + Option + 4 ] 并在 {Document-Label} 上为它写一个名称。

  3. In the AttributeInspector[ Cmd + Option + 5 ], change the {Style} from "Plain" to "Default", and the {Type} to "Custom".在 AttributeInspector[ Cmd + Option + 5 ] 中,将 {Style} 从“Plain”更改为“Default”,将 {Type} 更改为“Custom”。

  4. And since you are showing any text on the button Ui, In the AttributeInspector[ Cmd + Option + 5 ] set an {Image} from you Assets.由于您在按钮 Ui 上显示任何文本,因此在 AttributeInspector[ Cmd + Option + 5 ] 中从您的资产中设置 {Image}。

Build, Run, and have a nice day!构建,运行,并祝您有美好的一天!

To hide the back button text globally (iOS 14+):全局隐藏后退按钮文本(iOS 14+):

extension UINavigationController {
  open override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()
    navigationBar.topItem?.backButtonDisplayMode = .minimal
  }
}

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

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