移除iOS UIBarButtonItem的标题文本

199

我的目标是从一个UIBarButtonItem的“返回”按钮中删除文本,只留下导航栏上的蓝色箭头。请注意,我正在为iOS 7开发。我尝试了几种方法,包括但不限于:

这是一种图片方法,但我不喜欢(图片看起来不协调):

UIBarButtonItem *barBtnItem = [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"iOS7BackButton"] style:UIBarButtonItemStylePlain target:self action:@selector(goToPrevious:)];
self.navigationItem.leftBarButtonItem = barBtnItem;

我尝试的另一种方法是这样的,但它根本行不通(没有显示任何内容):

UIBarButtonItem *barBtn = [[UIBarButtonItem alloc]init];
barBtn.title=@"";
self.navigationItem.leftBarButtonItem=barBtn;

我想要实现的是类似于 iOS 7 音乐应用中仅带有单个箭头的返回按钮。

谢谢。


看这个答案:https://dev59.com/RWMk5IYBdhLWcg3w5R6k#20300577 - ayalcinkaya
为什么不拍下您的需求图像?然后在leftBarButtonItem中引用它。 - Vishal Sharma
我没有使用图片方法的原因是,一是很难得到一个完美的后退按钮图像,二是图像会存在某种形式的错位,看起来不自然,这就是为什么我去StackOverflow寻求帮助来实现本地化。 - Pan Ziyue
39个回答

6
事实上,您只需要一个技巧就可以做到这一点:
覆盖UINavigationBar类并添加以下代码行:
- (void)layoutSubviews{
    self.backItem.title = @"";
    [super layoutSubviews];
}

然后,使用这个自定义的UINavigationBar类来初始化你的UINavigationController。等等。 UINavigationController * navController = [[UINavigationController alloc] initWithNavigationBarClass:[CBCNavigationBar class] toolbarClass:nil];

希望这可以帮到你。


这对我有用。尽管在iOS 7上,推送动画似乎有轻微的卡顿:标题似乎为返回按钮腾出空间,然后居中,因为没有返回按钮。 - zekel
尝试使用自定义的titleView而不是直接设置navigationItem.title,我认为这应该可以解决你的问题。 - rordulu
这个解决方案非常棒,因为它适用于每个具有子类的navigationBar。谢谢。 - Yetispapa

6

解决这个问题的简单方法是在viewDidLoad中设置自定义标题视图,对于iOS7和6都适用:

- (void)viewDidLoad {

    [super viewDidLoad];

    UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
    titleLabel.text = self.title;
    titleLabel.backgroundColor = [UIColor clearColor];

    [titleLabel sizeToFit];

    self.navigationItem.titleView = titleLabel;
}

然后,在视图即将出现的时候,您可以安全地调用:

viewWillAppear:

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

由于您的标题视图是自定义视图,因此在导航堆栈中返回时不会被覆盖。

我只需要代码的后半部分,而不是空白的UILabel。我在viewWillAppear中调用[self.navigationItem.backBarButtonItem setTitle:@" "];,但在解除模态视图后呈现的视图上无效。 - Diziet

5

我能够通过参考DonnaLea的回答拼凑出一些东西。这是在我的UIViewController子类中实现该解决方案的方式:

var backItemTitle:String?

override func viewDidLoad() {
    super.viewDidLoad()

    //store the original title
    backItemTitle = self.navigationController?.navigationBar.topItem?.title

    //remove the title for the back button
    navigationController?.navigationBar.topItem?.title = ""
}

override func willMoveToParentViewController(parent: UIViewController?) {
    super.willMoveToParentViewController(parent)
    if parent == nil {

        //restore the orignal title
        navigationController?.navigationBar.backItem?.title = backItemTitle
    }
}

原回答存在的问题是,当您弹回到控制器时,它会删除控制器的标题。在viewWillDisappear中尝试重置标题太晚了,这会导致标题突然弹回而不是流畅地动画。但是,willMoveToParentViewController发生得更早,可以实现正确的行为。
注意:我只使用普通的UINavigationController推送/弹出进行了测试。在其他情况下可能会有额外的意外行为。

4
在您的第一个ViewController的prepareForSegue:方法中,您将该视图的标题设置为@"",因此当下一个视图被推送时,它将显示前一个ViewController的标题,该标题将为@""。
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    self.navigationItem.title = @" ";
}

这样做的唯一问题是当你按下返回按钮时,你之前的视图将没有标题,所以你可能需要在viewWillAppear中再次添加它:
- (void)viewWillAppear:(BOOL)animated{
    self.navigationItem.title = @"First View Title";
}

我不是很喜欢这种解决方案,但它能正常工作,我没找到其他方法。


4

SWIFT 3

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

3
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefaultPrompt];
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(10.0, NSIntegerMin) forBarMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor],
                                                               NSFontAttributeName:[UIFont systemFontOfSize:1]}
                                                    forState:UIControlStateNormal];

1
请在您的答案中添加解释。 - Alex
1 让颜色与导航栏相同 2 将文本大小调小,以免挤压标题 - Bill Xie
我已经审查了你的回答,你应该始终支持你的答案。 - Alex

3
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                [UIColor clearColor],UITextAttributeTextColor,
                                nil];
    
    [[UIBarButtonItem appearance] setTitleTextAttributes:attributes
                                                forState:UIControlStateNormal];

我遇到了同样的问题,我是这样解决的。
--编辑--
如果您真的想要删除所有UIBarbuttonItem的标题文本,则以下是解决方案。如果您只想删除后退栏按钮项的标题,则没有一个简单的便捷解决方案。在我的情况下,由于只有几个UIBarButtonItems需要显示标题文本,因此我只更改了那些特定按钮的titleTextAttributes。如果您想更加具体,请使用下面的代码,它将仅更改导航栏按钮。
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
                                [UIColor clearColor],UITextAttributeTextColor,
                                nil];
    
[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil] setTitleTextAttributes:attributes
                                                forState:UIControlStateNormal];

--编辑-- 关于Swift
let BarButtonItemAppearance = UIBarButtonItem.appearance()
        BarButtonItemAppearance.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.clear], for: .normal)
        BarButtonItemAppearance.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.clear], for: .highlighted)
        BarButtonItemAppearance.setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.clear], for: .selected)

1
这对我来说是有效的,但是当点击返回时,你可能会短暂地看到文本。 - Diziet
3
@Diziet 请尝试为UIControlStateHighlighted状态添加相同的内容。 - CoderPug
2
这个可以正常工作,但是它也“隐藏”了所有其他按钮,而不仅仅是返回按钮... 有什么解决办法吗? - Urkman

3

以上答案都无法帮助我。但是有一个技巧 - 我只是在推送视图控制器的标题(返回按钮所在的位置)之前清除了它。

因此,当上一个视图没有标题时,在iOS 7上,返回按钮将只有一个箭头,没有文本。

在推送视图的 viewWillAppear 中,我恢复了原始标题。


1
嗯,这个技巧很有效。但是看起来上面的文字有时会闪烁。虽然不是一个很好的解决方法,但仍然是一个好方法。+1 - Pan Ziyue

3

使用子类navigationController可以去掉“返回”按钮。

我正在使用它通过应用程序永久地删除它。

//.h
@interface OPCustomNavigationController : UINavigationController 

@end

//.m
@implementation OPCustomNavigationController

- (void)awakeFromNib
{
    [self backButtonUIOverride:YES];
}

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    [self backButtonUIOverride:NO];

    [super pushViewController:viewController animated:animated];
}

- (void)backButtonUIOverride:(BOOL)isRoot
{
    if (!self.viewControllers.count)
        return;

    UIViewController *viewController;

    if (isRoot)
    {
        viewController = self.viewControllers.firstObject;
    }
    else
    {
        int previousIndex = self.viewControllers.count - 1;

        viewController = [self.viewControllers objectAtIndex:previousIndex];
    }

    viewController.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@""
                                                                                       style:UIBarButtonItemStylePlain
                                                                                      target:nil
                                                                                      action:nil];
}

@end

2

Swift 3.1 您可以通过实现UINavigationController的委托方法来完成此操作。它将仅隐藏带有返回按钮的标题,我们仍将获得返回箭头图像和默认功能。

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接