UINavigationBar Скрыть текст кнопки "Назад"

104

Как я могу скрыть текст кнопки «Назад» от контроллера навигации UIN? У меня будет только «<», а не «<Назад»

Нильс
источник
1
вы не можете изменять текст по умолчанию, вместо этого попробуйте navigationItem.leftBarButtonItem, чтобы установить пользовательскую кнопку возврата
BaSha
См. Мой ответ ниже, если вам нужно глобальное решение с использованием прокси внешнего вида.
fl034

Ответы:

107

В конструкторе интерфейса вы можете выбрать элемент навигации предыдущего контроллера и изменить Back Buttonстроку на то, как вы хотите, чтобы кнопка возврата отображалась как.Например, если вы хотите, чтобы он был пустым, просто поставьте пробел.

Вы также можете изменить его с помощью этой строки кода:

[self.navigationItem.backBarButtonItem setTitle:@"Title here"];

Или в Swift :

self.navigationItem.backBarButtonItem?.title = ""

rebello95
источник
2
Замечательный совет, касающийся установки пустого места в конструкторе интерфейсов ... :-D
Фелипе Ферри
9
Конструктор интерфейсов и программные маршруты Swift не работали у меня в XCode 8.3.2, Swift 3
agrippa
Вы можете проверить мое очень простое решение для скрытия всех кнопок назад в приложении. PS: Требуется нулевая строка собственного кода
Pratik Jamariya
2
Если Back Buttonв IB уже пусто, просто добавьте пробел Backи покажите стрелку.
Tejas K
3
В настоящее время этот метод работает только в построителе интерфейсов. Установка этого из кода не работает, вместо установки только заголовка, вам нужно установить весь backBarButtonItem следующим образом: navigationItem.backBarButtonItem = UIBarButtonItem (title: "", style: .plain, target: nil, action: nil)
Leszek Szary
81

Вы также можете сделать это с помощью раскадровки. В инспекторе атрибутов элемента навигации предыдущего контроллера вы могли установить "" в поле кнопки "Назад". См. Изображение ниже. Замените «Ваш заголовок здесь» на «». Тем самым вы добьетесь желаемого результата. Вам больше не нужно возиться с «Заголовком».

Программно вы могли бы использовать

[self.navigationItem.backBarButtonItem setTitle:@" "];

где self относится к контроллеру, который подталкивает желаемый контроллер View.

Xcode view controller navigation item

Образец до, после панели навигации

Перед Before

После After

Шахзин К.С.
источник
7
Это отлично работает, если это установлено в раскадровках. Просто убедитесь, что на панели навигации есть элемент навигации, чтобы его можно было настроить.
11
В iOS 9 / Xcode 7.3 backBarButtonItemпрограммная установка не работает, но установка через раскадровку работает.
Скотт Гарднер,
@ScottGardner, установка backBarButtonItemпрограммно у меня работает в iOS 9.
Suragch
Если у вас нет панели навигации на вашем экране, возможно, потому, что ее нужно скрыть, вы можете добавить элемент навигации в раскадровке к предыдущему контроллеру представления и установить для его кнопки возврата значение «».
Мартин Бергер
Решение отлично работало, и его очень легко реализовать в Xcode 9.2 / iOS 11.
Рэй Хантер
79

Реализовать можно UINavigationControllerDelegateтак:

Старый Свифт

func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
    let item = UIBarButtonItem(title: " ", style: .Plain, target: nil, action: nil)
    viewController.navigationItem.backBarButtonItem = item
}

Swift 4.x

class MyNavigationController: UINavigationController, UINavigationControllerDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        self.delegate = self
    }

    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        let item = UIBarButtonItem(title: " ", style: .plain, target: nil, action: nil)
        viewController.navigationItem.backBarButtonItem = item
    }
}

backBarButtonItemэто nilпо умолчанию , и это влияет на следующий толкнул контроллер, так что вы просто установить его для всех контроллеров

Без пустоты
источник
6
Спасибо! Это единственное решение, которое сработало (без каких-либо проблем) после просмотра 4 повторяющихся вопросов и десятков ответов.
inket
1
У меня уже был подкласс контроллера навигации, который я превратил в его собственный делегат, и он отлично работал. Однако следует обновить для Swift 3.
Дин Келли
Отличное решение, спасибо, единственное, которое у меня стабильно работало.
Эллиот Дэвис
Работает как шарм.
tounaobun
48

Установка заголовка кнопки возврата на @""или nilне будет работать. Вам нужно сделать всю кнопку пустой (без заголовка или изображения):

Цель-C

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

Swift

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

Это должно быть сделано на контроллере представления, который находится поверх вашего контроллера представления в стеке навигации (то есть, откуда вы переходите к своему VC через pushViewControllerметод)

шакал
источник
2
Спасибо, это работает! В быстром: self.navigationItem.backBarButtonItem = UIBarButtonItem (title: "", style: .Plain, target: nil, action: nil)
mostworld77
отличный ответ ... правильно указывает, что простого изменения заголовка backBarButtonItem по умолчанию недостаточно. Бонусные баллы за упоминание о том, что backBarButtonItem должен быть установлен в предыдущем контроллере представления.
Crazed'n'Dazed
30

Другое решение этой проблемы для ситуаций, когда у вас много контроллеров представления, - это использовать UIAppearanceпрокси для эффективного скрытия текста заголовка кнопки возврата, например:

UIBarButtonItem *navBarButtonAppearance = [UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil];

[navBarButtonAppearance setTitleTextAttributes:@{
    NSFontAttributeName:            [UIFont systemFontOfSize:0.1],
    NSForegroundColorAttributeName: [UIColor clearColor] }
                                      forState:UIControlStateNormal];

Это решение отобразит текст в виде крошечной прозрачной точки, аналогично ручной установке заголовка кнопки «Назад» @" ", за исключением того, что оно влияет на все кнопки панели навигации.

Я не предлагаю это как общее решение проблемы, потому что это влияет на все кнопки панели навигации. Он меняет парадигму, так что вы выбираете, когда показывать заголовки кнопок, а не когда скрывать заголовки.

Чтобы выбрать, когда показывать заголовки, либо вручную восстановите атрибуты текста заголовка по мере необходимости, либо создайте специализированный подкласс, UIBarButtonItemкоторый делает то же самое (возможно, с другим UIAppearanceпрокси).

Если у вас есть приложение, в котором нужно скрыть большинство заголовков кнопок «Назад», и только несколько (или ни одной) кнопок навигации являются системными кнопками с заголовками, это может быть для вас!

(Примечание: изменение размера шрифта необходимо, даже если цвет текста четкий, чтобы длинные заголовки не вызывали смещения заголовка центральной панели навигации)

Адам Каплан
источник
Было самым простым решением для моей реализации. Спасибо.
Тревор Панхорст
3
Разве это не закрывает элементы кнопок левой панели, которые не являются кнопками возврата?
Кевинл 01
1
Да, я это заметил. «Это влияет на все кнопки панели навигации»
Адам Каплан
2
не должно ли это повлиять на все другие кнопки на панели навигации, включая элементы кнопок левой / правой панели?
Федор Волчёк
Да, более подробного требования он не указал.
Адам Каплан
29

Добавьте следующий код в viewDidLoad или loadView

self.navigationController.navigationBar.topItem.title = @"";  

Я тестировал его на iPhone и iPad с iOS 9

одни
источник
20
Это не очистило заголовок предыдущего контроллера представления?
CalZone
6
Не используйте, потому что это удалит последний заголовок экрана
evya 08
Если вам нужно сделать это из текущего контроллера представления, то, чтобы избежать удаления заголовка из предыдущего vc, лучше сделать это: navigationController? .NavigationBar.topItem? .BackBarButtonItem = UIBarButtonItem (title: "", style: .plain, target: nil, action: nil)
Leszek Szary
15

Вы можете добавить эту категорию Objective-C, чтобы все кнопки «Назад», созданные контроллером навигации, не имели текста. Я только что добавил его в свой файл AppDelegate.m.

@implementation UINavigationItem (Customization)

/**
 Removes text from all default back buttons so only the arrow or custom image shows up.
 */
-(UIBarButtonItem *)backBarButtonItem
{
    return [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
}

@end

PS - (Я не знаю, как заставить это расширение работать со Swift, у него были странные ошибки. Приветствуются правки, чтобы добавить версию Swift)

терадил
источник
Это дает титул «Назад», а не скрывает титул
Радж Аггравал
Действительно, как overrideэто сделать в быстром темпе. Очень интересный вопрос
Андрей Гаган
@teradyl это лучший ответ.
aks.knit1108
@ Андрей Гаган, смотрите мой ответ
Абирами Бала
Это работает на iOS 9.0–10.3.3, но на iOS 11+ не работает.
Sihad Begovic
14

Я пробовал несколько выше и ниже, но они не работали. Это сработало для меня:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.navigationController?.navigationBar.topItem?.title = ""
}
Катанор
источник
1
Если вам нужно сделать это из текущего контроллера представления, то, чтобы избежать удаления заголовка из предыдущего vc, лучше сделать это: navigationController? .NavigationBar.topItem? .BackBarButtonItem = UIBarButtonItem (title: "", style: .plain, target: nil, action: nil)
Leszek Szary
11

Единственное, что работает без побочных эффектов, - это создание настраиваемой кнопки возврата. Пока вы не предоставляете настраиваемое действие, работает даже жест слайда.

extension UIViewController {
func setupBackButton() {
    let customBackButton = UIBarButtonItem(title: " ", style: .plain, target: nil, action: nil)
    navigationItem.backBarButtonItem = customBackButton
}}

К сожалению, если вы хотите, чтобы все кнопки возврата не имели заголовков, вам необходимо настроить эту настраиваемую кнопку возврата во всех контроллерах представления: /

override func viewDidLoad() {
    super.viewDidLoad()

    setupBackButton()
}

Очень важно установить в качестве заголовка пробел, а не пустую строку.

Сезар Синьори
источник
9

чтобы программно удалить текст из кнопки возврата, используется ниже Код, это будет работать с xcode7 и выше.

self.navigationController.navigationBar.topItem.title = @ "";

или

manualLy в раскадровках, выберите панель навигации на контроллере представления и вставьте "" в текст кнопки возврата.

это будет работать. Спасибо

Джиоти Бабу Пакалз
источник
2
Этот также удалит заголовок навигационного
элемента
Я отредактировал ваш ответ на это: self.navigationController?.navigationBar.topItem?.title = " "в Xcode 9 и работал!
MHSFisher
Если вам нужно сделать это из текущего контроллера представления, то, чтобы избежать удаления заголовка из предыдущего vc, лучше сделать это: navigationController? .NavigationBar.topItem? .BackBarButtonItem = UIBarButtonItem (title: "", style: .plain, target: nil, action: nil)
Leszek Szary
8

Текущий ответ не работал. Я хотел полностью удалить заголовок , но текст «назад» никуда не делся.

Вернитесь к предыдущему контроллеру представления и установите его свойство title:

self.title = @" ";

ТОЛЬКО работает, когда предыдущий контроллер представления не имеет заголовка

ChrisHaze
источник
@ZevEisenberg убедитесь, что свойство устанавливается до отображения в жизненном цикле контроллера представления. Это означает установить его в методах viewDidLoad или viewWillAppear.
ChrisHaze,
1
также не забудьте поставить пробел между кавычками.
ChrisHaze,
1
На самом деле это сработало для меня без пробелов; просто хорошая старая пустая строка @"".
Зев Айзенберг,
1
@ZevEisenberg, Когда я впервые придумал решение, оно было раньше в Xcode 5. Единственным способом работы было использование пробела, поэтому я включил его в пример кода. Обновление Xcode 6 должно было включать его. Полезно знать -
спасибо
Я также использовал свой подход, который все еще работает, и удалил стандартную стрелку назад.
ChrisHaze
5

Альтернативный способ - использовать собственный класс NavigationBar.

class NavigationBar: UINavigationBar {

    var hideBackItem = true
    private let emptyTitle = ""

    override func layoutSubviews() {
        if let `topItem` = topItem,
            topItem.backBarButtonItem?.title != emptyTitle,
            hideBackItem {
            topItem.backBarButtonItem = UIBarButtonItem(title: emptyTitle, style: .plain, target: nil, action: nil)
        }

        super.layoutSubviews()
    }

}

То есть при этом удаляются заглавия всего проекта. Просто установите собственный класс для UINavigationController.

LLIAJLbHOu
источник
4

Установите заголовок предыдущего VC в "" строку с пробелом. а заголовок с кнопкой возврата будет заменен строкой с одним пробелом.

Self.title = " "

На Back нажмите еще раз, чтобы вернуть заголовок к исходному в viewWillAppear.

Мохит Кумар
источник
4

Используйте обычай, NavigationControllerкоторый отменяетpushViewController

class NavigationController: UINavigationController {  
  override func pushViewController(_ viewController: UIViewController, animated: Bool) {
    viewController.navigationItem.backBarButtonItem =
      UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
    super.pushViewController(viewController, animated: animated)
  }
}
onmyway133
источник
4

Уже много ответов, вот мои два цента по этой теме. Я нашел этот подход действительно надежным. Вам просто нужно поместить это в viewController перед переходом.

Swift 4:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
Codetard
источник
2
Да! Спасибо :)
Hews
3

Я перепробовал все в этом посте. Единственное рабочее решение - это @ VoidLess's

Вот тот же ответ, но более полный

class CustomNavigationController: UINavigationController {

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        self.delegate = self
    }
}


// MARK:UINavigationControllerDelegate
extension CustomNavigationController {
    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        viewController.navigationItem.backBarButtonItem = UIBarButtonItem(title: " ", style: .plain, target: nil, action: nil)
    }
}
Христос Чаджикириаку
источник
3

Это мое разрешение для iOS11, я меняю внешний вид UIBarButtonItem в applicationDidFinishLaunchingWithOptions:

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

Вы не можете изменить смещение Y, потому что оно изменит положение кнопки задней панели также в iOS11, но это нормально в iOS10 и ниже.

ВикторЧи
источник
1
Это работает, но во время анимации вы можете видеть, как предыдущий заголовок перемещается влево. Выглядит немного глючно.
Джонатан
2

В Swift3,

Если вы установите глобальную настройку

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    // ..

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


    // ...

}
taku_oka
источник
1
Обратите внимание, что это также изменит цвет на прозрачный для всех других кнопок панели, которые могут быть где-то в вашем приложении, а не только для кнопок возврата.
Leszek Szary
2

Swift 3.1 Вы можете сделать это, реализовав метод делегата UINavigationController.

func navigationController(_ navigationController: UINavigationController, 
                          willShow viewController: UIViewController, animated: Bool) {

    /** It'll hide the Title with back button only,
     ** we'll still get the back arrow image and default functionality.
     */
    let item = UIBarButtonItem(title: " ", style: .plain, target: nil, 
                               action: nil)
    viewController.navigationItem.backBarButtonItem = item
}
SMMoinuddin. Шуво
источник
Лучший ответ!
evya 08
2

Для тех, кто хочет глобально скрыть заголовок кнопки возврата.

Вы можете Swizzle viewDidLoadиз UIViewControllerтак.

+ (void)overrideBackButtonTitle {

    NSError *error;

    // I use `Aspects` for easier swizzling.

    [UIViewController aspect_hookSelector:@selector(viewDidLoad)
                              withOptions:AspectPositionBefore
                               usingBlock:^(id<AspectInfo> aspectInfo)
    {

        UIViewController *vc = (UIViewController *)aspectInfo.instance;

        // Check whether this class is my app's view controller or not.
        // We don't want to override this for Apple's view controllers,
        // or view controllers from external framework.

        NSString *className = NSStringFromClass([vc class]);
        Class class = [NSBundle.mainBundle classNamed:className];
        if (!class) {
           return;
        }

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

    } error:&error];

    if (error) {
        NSLog(@"%s error: %@", __FUNCTION__, error.localizedDescription);
    }

}

Использование:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [[self class] overrideBackButtonTitle];
    return YES;
}
nRewik
источник
2

Если вы ориентируетесь на iOS 13 и новее, вы можете использовать этот новый API, чтобы глобально скрыть заголовок кнопки «Назад» .

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

UINavigationBar.appearance().standardAppearance.backButtonAppearance = backButtonAppearance
UINavigationBar.appearance().compactAppearance.backButtonAppearance = backButtonAppearance
UINavigationBar.appearance().scrollEdgeAppearance.backButtonAppearance = backButtonAppearance
fl034
источник
1
Это не оптимально. Если пользователь касается метки с открытым текстом, обратное действие все равно запускается.
dvdblk,
1

Я боролся с этим, потому что у меня был собственный контроллер навигации. Я смог удалить текст заднего элемента во всех контроллерах представления с помощью этого кода в моем пользовательском классе контроллера навигации. override func viewDidLayoutSubviews() { self.navigationBar.backItem?.title = "" }

Это удаляет все заголовки задних элементов с помощью этого настраиваемого контроллера навигации.

Эми.Р
источник
1
Обновление для этого: это работает, но есть странная задержка при загрузке, которая меня беспокоит. Теперь я добавил это 'let BarButtonItemAppearance = UIBarButtonItem.appearance () BarButtonItemAppearance.setTitleTextAttributes ([NSAttributedStringKey.foregroundColor: UIColor.clear], for: .normal) »в делегате приложения didLaunchWithOptions работает отлично!
Amy.R
0

В iOS 11 мы обнаружили, что установка UIBarButtonItemочень маленького значения шрифта / цвета текста внешнего вида или прозрачного цвета приведет к исчезновению другого элемента панели (система больше не учитывает класс элемента UIBarButton, она преобразует его в a _UIModernBarButton). Также установка смещения обратного текста за пределы экрана приведет к миганию во время интерактивного всплывающего окна.

Итак, мы взяли addSubView:

+ (void)load {
    if (@available(iOS 11, *)) {
        [NSClassFromString(@"_UIBackButtonContainerView")     jr_swizzleMethod:@selector(addSubview:) withMethod:@selector(MyiOS11BackButtonNoTextTrick_addSubview:) error:nil];
    }
}

- (void)MyiOS11BackButtonNoTextTrick_addSubview:(UIView *)view {
    view.alpha = 0;
    if ([view isKindOfClass:[UIButton class]]) {
        UIButton *button = (id)view;
        [button setTitle:@" " forState:UIControlStateNormal];
    }
    [self MyiOS11BackButtonNoTextTrick_addSubview:view];
}
sbhhbs
источник
0
-(void)setNavigationItems{
     UIBarButtonItem *leftBarButtonItem=[[UIBarButtonItem alloc]initWithTitle:@"**Your title here**" style:UIBarButtonItemStyleBordered target:self action:@selector(backButtonClicked)];   
     self.navigationController.navigationBar.topItem.backBarButtonItem=leftBarButtonItem;
}
-(void)backButtonClicked{
    [self.navigationController popViewControllerAnimated:YES];
}
нику
источник
0

Обратный текст берется из , последнего контроллера просмотра navigationItem.titleи navigationItem.titleустанавливается автоматически self.title. Самый простой способ решить проблему - это крючок setTitle:, убедитесьnavigationItem.title = @""

Поместите этот код по AppDelegate.mжеланию, и все будет в порядке。

    [UIViewController aspect_hookSelector:@selector(setTitle:)
                              withOptions:AspectPositionAfter
                               usingBlock:^(id<AspectInfo> aspectInfo, NSString *title) {
        UIViewController *vc = aspectInfo.instance;
        vc.navigationItem.titleView = ({
            UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
            titleLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline];
            titleLabel.text = title;
            titleLabel;
        });
        vc.navigationItem.title = @"";
    } error:NULL];

Более подробная информация на https://www.jianshu.com/p/071bc50f1475 (Simple Chinease).

fengxing
источник
0

Мое решение: - XCode: 10.2.1 - Swift: 5

  • Родительский контроллер представления:
    • self.title = ""
  • Дочерний контроллер просмотра:
    • self.navigationItem.title = "Your title" // установить заголовок для viewcontroller
Фуоклуонг
источник
0

XCode 11.5 Swift 5

Очень простой - хотя, возможно, немного хакерский - способ сделать это программно, если вам не нужна настраиваемая кнопка возврата, - это установить размер шрифта равным нулю в контроллере представления, который вы помещаете в стек, вызывая что-то вроде этого из viewDidLoad

private func setupNavBar() {
    let appearance = UINavigationBarAppearance()
    appearance.configureWithDefaultBackground()
    
    let backButtonAppearance = UIBarButtonItemAppearance()
    backButtonAppearance.normal.titleTextAttributes = [.font: UIFont(name: "Arial", size: 0)!]
    appearance.backButtonAppearance = backButtonAppearance

    navigationItem.standardAppearance = appearance
    navigationItem.scrollEdgeAppearance = appearance
    navigationItem.compactAppearance = appearance
}
Pakchoiandbacon
источник
-1

Наконец-то нашли идеальное решение, чтобы скрыть задний текст по умолчанию во всем приложении.

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

UIBarButtonItem.appearance().setBackButtonBackgroundImage(#imageLiteral(resourceName: "transparent"), for: .normal, barMetrics: .default)
Лалит Кумар
источник
-2

Следующий метод работает на iOS 11 и не дает сбоев в других версиях iOS. Это может привести к отклонению вашего приложения в обзоре App Store, поскольку и UIModernBarButton, и UIBackButtonContainerView являются частными API. Поместите в AppDelegate.

    if
        let UIModernBarButton = NSClassFromString("_UIModernBarButton") as? UIButton.Type,
        let UIBackButtonContainerView = NSClassFromString("_UIBackButtonContainerView") as? UIView.Type {

        let backButton = UIModernBarButton.appearance(whenContainedInInstancesOf: [UIBackButtonContainerView.self])
        backButton.setTitleColor(.clear, for: .normal)
    }
Патрик
источник
Это может привести к отклонению вашего приложения в обзоре App Store, поскольку и UIModernBarButton, и UIBackButtonContainerView являются частными API.
Groot
Спасибо @Groot, добавил свое предупреждение.
Патрик
-5

Это из моего кода xamarin.forms, класс происходит от NavigationRenderer

NavigationBar.Items.FirstOrDefault().BackBarButtonItem = new UIBarButtonItem( "", UIBarButtonItemStyle.Plain, null);
Pinkladyla
источник