Удалить текст с кнопки «Назад», сохранив значок


96

Я хочу удалить текст с кнопки «Назад», но хочу сохранить значок. я пытался

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

Однако при этом полностью удаляются текст и значок.

Ответы:


99

Метод @ rmd2 почти правильный, но вместо этого вы должны выбрать панель навигации контроллера, на которую будет указывать кнопка " "«Назад», и ввести поле «Кнопка возврата».

введите описание изображения здесь


1
худший вариант, если у viewcontroller нет панели навигации, мне придется добавить, чтобы удалить текст
Daniel Beltrami

144

Я знаю, что на это уже есть ответ, но вы также можете сделать это в коде (если вы работаете с перьями)

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

Добавьте указанное выше в первый контроллер представления.

Обратите внимание, что вам нужно сделать это для каждого нажимающего контроллера представления. Итак, если у вас есть 3 контроллера представления, и вы хотите удалить задний текст со всех из них, вам придется добавить строку в контроллеры представления 1 и 2.


5
Это лучшее решение, которое я видел до сих пор, не доставляет мне никаких проблем
lostAtSeaJoshua

5
.Plainбыл изменен на .plain. Без заглавной буквы p.
Gal

Отлично..! Это то, что я хочу.
JD.

Лучшее решение. Спасибо.
Баран Эмре

1
@ GastónAntonioMontes, он работает на iOS13, но это немного счетчик интуитивно: пустой заголовок backBarButtonItem должен быть объявлен на толкающей контроллере представления, а не толкнул один
Мартин

51

После долгого поиска я нашел лучшее и простое решение, это повлияет на все viewControllers, написанные в Swift 4.2, а также работающие в Swift 5.

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

Добро пожаловать, @ e.dimitrow
iOS Lifee

1
Работает как шарм
Джерри Окафор

5
Обратите внимание, что это будет работать только в том случае, если ваш ViewController содержится в Storyboard или Nib ...
Натаниэль Блумер

1
Гениальное решение!
WM

3
Раньше это работало для меня, но больше не работает (это все еще работает на симуляторах iOS 12, только не на последней iOS 13) ...
Таня

37

Текст кнопки «Назад» зависит от заголовка основного представления.

Хитрость заключается в том, чтобы очистить заголовок, если главное представление исчезнет, ​​и установить его снова, если оно появится снова:

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

Swift:

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, метод viewWillDisappear из начального searchController не вызывается, поэтому заголовок все еще там
H4Hugo

Это не лучший подход, если вы ищете решение для экранов во всем приложении. - Если вы добавите этот код в какой-то «Базовый контроллер представления», viewWillDisappear первого контроллера представления будет вызываться после viewDidAppear второго контроллера представления (где вы обычно устанавливаете заголовок) ... это испортит заголовки. Лучший способ - перезаписать кнопку «Назад»
Митра Сингам

Идеальное решение, спасибо
SURESH SANKE

28

Если вам нужна стрелка назад, то следующий код поместите в файл AppDelegate в метод didFinishLaunchingWithOptions.

Для Свифта

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

2
мне нравится этот, потому что вы можете стандартизировать стиль своего приложения в одном файле и вызвать его один раз из делегата приложения
Aaronium112

4
Это действительно хорошее и быстрое решение, но ... это может быть сложно, если у вас есть другие кнопки на панели, кроме задней
:)

3
Одно наблюдение: если вы реализуете только атрибут «.normal», вы увидите текст при щелчке. Добавьте одну и ту же строку для «.selected», «.highlighted» и «.disabled». чтобы убедиться, что вы не видите мерцающий текст.
Nick N

1
Я думаю, это будет иметь побочный эффект, другие кнопки на панели, кроме кнопок назад, также будут затронуты и будут иметь четкий цвет текста :(
dhin

24

В моем случае для пользовательского значка и заголовка это помогло (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

Я решил эту проблему, добавив "" в заголовок StoryBoard предыдущего ViewController. Просто пространство, а не пустое; D

введите описание изображения здесь


Мне нужно, чтобы предыдущий экран имел заголовок, поэтому я думаю, что это не сработает для меня.
lmiguelvargasf 08

2
Я вычеркнул этот заголовок, но заголовок все еще
появляется в

1
не очищайте поле Заголовок, вставьте "" (пробел) в поле кнопки "Назад"
Кирилл С.

13

Наконец-то нашел идеальное решение.

Просто добавьте одно прозрачное изображение и добавьте следующий код в свой AppDelegate.

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

1
Это определенно лучший ответ. Раньше я использовал UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustmentхакер, рекомендуемый большинством других ответов, но он был сломан на iPhone X для контроллеров просмотра с длинными заголовками. Это решение работает безупречно.
Нед

3
Лучший ответ. Работал лучше, чем прозрачный цвет текста.
Уильям Т.

1
Лучшее решение, которое я использовал за последние 4 года! Вы делаете это один раз, в одном месте и для всех контроллеров просмотра !!!
korgx9

1
Когда я попробовал это с iOS 12, текст все еще появлялся рядом с изображением. :(
Шон МакМейнс 02

13

быстро 4

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

Спасибо, мне это помогло (Swift 4.0, Xcode 10.1, iOS 12.1.1), спасибо
infinity_coding7

3
НО, вы потеряете титул в родительском vc
Вэй Лу

1
Если присутствует большой заголовок, то topItem имеет большой заголовок. Не работает
Саранджит

11

Это работает для меня

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

1
Правильный. В iOS 13 navigationItem.backBarButtonItem не работает. Это сэкономило мне часы усилий. Спасибо
Manish

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 с текстом, нужно ли мне вручную изменять цвет переднего плана для этой кнопки?
kuzdu 09

1
Это хорошо, но когда вы нажимаете кнопку «Назад», он все еще показывает текст
Уильям Т.

Он работает, но в iOS 11 исчезают другие кнопки панели. Ответ Рафикула Хасана, приведенный выше, может решить проблему
huync

6

Если у вас есть ViewControllerA, и вы хотите перейти к ViewControllerB, в ViewControllerA вы должны установить текущий navigationItem с новым UIBarButtonItem и заголовком в строке с пустым пространством, прежде чем нажимать на другой контроллер представления:

Задайте заголовок в виде строки с пробелом, вы не можете установить nil или "" (пустая строка), потому что значение по умолчанию - nil

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

У меня было очень забавное поведение с текстом «Назад», снова появляющимся, даже когда заголовок был установлен на «» (и проверялся как таковой) в ViewControllerB(хотя это всегда работало до сих пор, с моим конкретным крайним случаем), это было единственное решение, которое сработало для меня
10623169

6

Поместите этот код в каждый 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

Чтобы удалить из всех контроллеров представления в стеке контроллеров навигации:

подкласс 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)

2

Детали

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

Результат

введите описание изображения здесь


2

Вы можете удалить текст с кнопки возврата, используя метод делегата 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)
    }
    
}

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

У меня есть контроллер, который всегда показывает обратный текст с кнопкой возврата. Итак, приведенный выше код не работает в моем случае
Шахбаз Акрам

1

Вы должны выбрать панель навигации контроллера, ОТ которой будет указывать кнопка «Назад», и ввести «» в поле «Кнопка возврата».

например, если вы нажимаете контроллер A на контроллер B, поместите пробел в панель навигации контроллера A.


1

Xcode 10, Swift 4+

Аналогичный ответ на другие здесь, но стоит отметить, что если текст все еще не очищен, вам нужно нажать пробел, а затем Enter.

введите описание изображения здесь


1

Один из вариантов , чтобы переопределить все ViewControllersдля меня было расширить UINavigationControllerи установить backBarButtonItemиз topViewController.

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/


0

В Xcode 9.2 со Swift это работало так:

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

Простой программный способ без нежелательных побочных эффектов - это инициализация navigationItem.backBarButtonItem с пустым элементом в методе awakeFromNib исходного контроллера (того, с которого вы переходите ):

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

Примечание. Если вы инициализировали кнопку «Назад» позже, как в методе viewDidLoad () , то потеряете функцию обратного смахивания (смахивание от левого края вправо возвращает вас на один шаг назад в стеке навигации).

Затем, если вам нужны разные тексты кнопок возврата для разных контроллеров назначения, и если вы используете переходы, вы можете установить заголовок в методе 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
        }
    }
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.