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


104

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


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


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

Ответы:


107

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

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

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

Или в Swift :

self.navigationItem.backBarButtonItem?.title = ""


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 = @" ";

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


@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.


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

4

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

Swift 4:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}

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)


    // ...

}

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
}

Лучший ответ!
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;
}

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

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

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


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
}

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