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

96

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

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

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

lmiguelvargasf
источник

Ответы:

99

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

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

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

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

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

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

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

d9rad
источник
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)
    }  
}
iOS Lifee
источник
Добро пожаловать, @ 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

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

rmd2
источник
Мне нужно, чтобы предыдущий экран имел заголовок, поэтому я думаю, что это не сработает для меня.
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)
}
RomanV
источник
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
источник
Могли бы вы объяснить?
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)

    }
}
мохман252
источник
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
        }
    }
}
Иржи Волейник
источник