【发布时间】:2014-07-14 06:04:15
【问题描述】:
如何隐藏 UINavigation 控制器的后退按钮文本? 我只会有“
【问题讨论】:
-
你不能修改默认文本,而是尝试使用navigationItem.leftBarButtonItem设置自定义返回按钮
-
如果您想要使用外观代理的全局解决方案,请参阅下面的答案。
标签: ios uinavigationcontroller
如何隐藏 UINavigation 控制器的后退按钮文本? 我只会有“
【问题讨论】:
标签: ios uinavigationcontroller
在界面构建器中,您可以选择前一个控制器的导航项并将Back Button 字符串更改为您希望后退按钮显示的样子。 如果你想让它空白,例如,只需放置一个空格。
你也可以用这行代码改变它:
[self.navigationItem.backBarButtonItem setTitle:@"Title here"];
或者在 Swift 中:
self.navigationItem.backBarButtonItem?.title = ""
【讨论】:
Back Button 在 IB 中已经是空白,只需添加一个空格即可搭乘 Back 并显示箭头。
你可以像这样实现UINavigationControllerDelegate:
func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
let item = UIBarButtonItem(title: " ", style: .Plain, target: nil, action: nil)
viewController.navigationItem.backBarButtonItem = item
}
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,它会影响下一个推送的控制器,所以你只需为所有控制器设置它
【讨论】:
您也可以通过情节提要来做到这一点。在前一个控制器的导航项的属性检查器中,您可以在“后退”按钮字段中设置“”。请参阅下图。将“您的标题”替换为“”。通过这样做,您将获得所需的结果。你不需要再弄乱“标题”了。
您可以通过编程方式使用
[self.navigationItem.backBarButtonItem setTitle:@" "];
其中 self 是指推送您想要的 View 控制器的控制器。
导航栏之前、之后的示例
之前
之后
【讨论】:
backBarButtonItem 不起作用,但通过情节提要进行设置。
backBarButtonItem works for me。
将后退按钮的标题设置为@"" 或nil 将不起作用。您需要将整个按钮设置为空(没有标题或图像):
[self.navigationItem setBackBarButtonItem:[[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil]];
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
这应该在导航堆栈中位于视图控制器顶部的视图控制器上完成(即从您通过 pushViewController 方法导航到 VC 的位置)
【讨论】:
对于有大量视图控制器的情况,此问题的另一个解决方案是使用UIAppearance 代理来有效地隐藏后退按钮标题文本,如下所示:
UIBarButtonItem *navBarButtonAppearance = [UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil];
[navBarButtonAppearance setTitleTextAttributes:@{
NSFontAttributeName: [UIFont systemFontOfSize:0.1],
NSForegroundColorAttributeName: [UIColor clearColor] }
forState:UIControlStateNormal];
此解决方案会将文本呈现为一个清晰的小圆点,类似于手动将后退按钮标题设置为 @" ",只是它会影响所有导航栏按钮。
我不建议将此作为该问题的通用解决方案,因为它会影响所有导航栏按钮。它翻转了范例,以便您选择何时显示按钮标题,而不是何时隐藏标题。
要选择何时显示标题,可以根据需要手动恢复标题文本属性,或者创建一个专用的 UIBarButtonItem 子类来做同样的事情(可能使用另一个 UIAppearance 代理)。
如果您的应用程序需要隐藏大部分后退按钮标题,并且只有少数(或没有)导航按钮是带有标题的系统按钮,那么这可能适合您!
(注意:即使文本颜色清晰,也需要更改字体大小,以确保长标题不会导致中心导航栏标题移位)
【讨论】:
在viewDidLoad或loadView中添加如下代码
self.navigationController.navigationBar.topItem.title = @"";
我在装有 iOS 9 的 iPhone 和 iPad 上对其进行了测试
【讨论】:
我在上面和下面尝试了一些,但它们没有用。这对我有用:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.navigationBar.topItem?.title = ""
}
【讨论】:
您可以添加此 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它。很有趣的问题
唯一没有副作用的方法是创建一个自定义后退按钮。只要您不提供自定义操作,即使滑动手势也有效。
extension UIViewController {
func setupBackButton() {
let customBackButton = UIBarButtonItem(title: " ", style: .plain, target: nil, action: nil)
navigationItem.backBarButtonItem = customBackButton
}}
不幸的是,如果您希望所有后退按钮都没有任何标题,则需要在所有视图控制器中设置此自定义后退按钮:/
override func viewDidLoad() {
super.viewDidLoad()
setupBackButton()
}
将空格设置为标题而不是空字符串非常重要。
【讨论】:
当前的答案不起作用。我想完全删除标题,但文本“back”并没有消失。
回到上一个视图控制器并设置它的title属性:
self.title = @" ";
仅在前一个 View Controller 没有标题时起作用
【讨论】:
@"".
以编程方式从后退按钮中删除文本,在代码下方使用,这将在 xcode7 及更高版本中工作。
self.navigationController.navigationBar.topItem.title = @" ";
或
手动在 storyboards 中,选择视图控制器上的导航栏并在后退按钮文本中添加“”。
这会奏效。谢谢
【讨论】:
self.navigationController?.navigationBar.topItem?.title = " " 并且工作了!
替代方式 - 使用自定义 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 设置自定义类。
【讨论】:
已经有很多答案了,这是我关于这个主题的两分钱。 我发现这种方法非常强大。 你只需要在 segue 之前把它放在 viewController 中。
斯威夫特 4:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
【讨论】:
将上一个 VC 的标题设置为带空格的 " " 字符串。并且带有后退按钮的标题将被替换为单个空格字符串。
Self.title = " "
在返回时再次将标题重置为 viewWillAppear 中的原始标题。
【讨论】:
使用覆盖pushViewController的自定义NavigationController
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)
}
}
【讨论】:
斯威夫特 5
viewController.navigationItem.backButtonDisplayMode = .minimal
【讨论】:
我尝试了这篇文章中的所有内容。唯一可行的解决方案是@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)
}
}
【讨论】:
这是我对 iOS11 的解决方案,我在 applicationDidFinishLaunchingWithOptions 中更改了 UIBarButtonItem 的外观:
UIBarButtonItem.appearance().setBackButtonTitlePositionAdjustment(UIOffsetMake(-100, 0), for:UIBarMetrics.default)
不能改变Y偏移,因为iOS11也会改变后退栏按钮的位置,但iOS10及以下可以。
【讨论】:
斯威夫特 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
}
【讨论】:
如果您的目标是 iOS 13 及更高版本,您可以使用this new 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
【讨论】:
这里大多数解决方案的问题是,在后面的项目上设置一个空文本不适用于长按后退按钮的新功能。它没有显示正确的标题,而是显示一个空列表
相反,您可以使用iOS14的新按钮显示模式或依赖iOS13的新外观API,将文本设置为0号。请注意,有些人正在使用颜色(透明),这也不起作用,因为它使用了空间并将其从您的标题中删除。如果标题足够长,你会看到它被剪掉了
结果代码:
public extension UINavigationBar {
func fixAppearance() {
if #available(iOS 14.0, *) {
topItem?.backButtonDisplayMode = .minimal
} else if #available(iOS 13.0, *) {
let newAppearance = standardAppearance.copy()
newAppearance.backButtonAppearance.normal.titleTextAttributes = [
.foregroundColor: UIColor.clear,
.font: UIFont.systemFont(ofSize: 0)
]
standardAppearance = newAppearance
} else {
topItem?.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
}
}
然后您只需要在视图控制器出现时调用该方法,因此您可以从基类调用它(例如在 viewWillAppear 上),或者像本文的其他答案一样向导航控制器添加一些委托.
【讨论】:
在 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)
// ...
}
【讨论】:
对于那些想要全局隐藏后退按钮标题的人。
您可以像这样调配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;
}
【讨论】:
我为此苦苦挣扎,因为我有一个自定义导航控制器。
我能够在我的自定义导航控制器类中使用此代码删除所有视图控制器中的后项文本
override func viewDidLayoutSubviews() {
self.navigationBar.backItem?.title = ""
}
这将使用此自定义导航控制器删除所有后退项目标题。
【讨论】:
在iOS 11中,我们发现将UIBarButtonItem外观的文字字体/颜色设置为非常小的值或清除颜色会导致其他bar item消失(系统不再支持UIBarButton item的类,它会转换它到_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];
}
【讨论】:
-(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];
}
【讨论】:
后面的文字来自上一个View Controller的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(简体中文)
【讨论】:
我的解决方案: - X代码:10.2.1 - 斯威夫特:5
【讨论】:
XCode 11.5 斯威夫特 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
}
【讨论】:
UINavigationControllerDelegate 的 navigationController(_, willShow:, animated:) 方法实现对我有用。
这里是完整的视图控制器源代码。如果您想在整个应用程序中应用此功能,请让所有视图控制器派生自 BaseViewController。
class BaseViewController: UIViewController {
// Controller Actions
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.delegate = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
updateNavigationBar()
}
//This is for custom back button image.
func updateNavigationBar() {
let imgBack = UIImage(named: "icon_back")
self.navigationController?.navigationBar.backIndicatorImage = imgBack
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = imgBack
self.navigationItem.backBarButtonItem = UIBarButtonItem()
}
}
extension BaseViewController: UINavigationControllerDelegate {
//This is to remove the "Back" text from back button.
func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
viewController.navigationItem.backBarButtonItem = UIBarButtonItem()
}
}
【讨论】: