Reputation: 5082
How can I customize the navigation back button in iOS 7 and above without title? (i.e. with the arrow only)
self.navigationItem.leftBarButtonItem = self.editButtonItem;
I'm just wondering if they have any self.backButtonItem;
OR
something like this?
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemBACK
target:self action:@selector(back)];
Upvotes: 239
Views: 263822
Reputation: 9296
backItem.title = ""
to using topItem.title = ""
navigationItem.hidesBackButton = true
& navigationItem.leftBarButtonItem
will lose the back gestureMy solution will change the image & keep the back gesture:
navigationController?.navigationBar.backIndicatorImage = UIImage(named: "back")
navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "back")
navigationController?.navigationBar.topItem?.title = ""
Upvotes: 1
Reputation: 91
SWIFT 4
For those looking to create custom back buttons as well as have their title removed please use the following piece of code within the view controller that's pushing the new one:
self.navigationController?.navigationBar.backIndicatorImage = UIImage(named: "close")
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "close")
self.navigationItem?.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
For a more universal use, do the following:
Create a universal function as follows:
func addCustomizedBackBtn(navigationController: UINavigationController?, navigationItem: UINavigationItem?) {
navigationController?.navigationBar.backIndicatorImage = UIImage(named: "close")
navigationController?.navigationBar.backIndicatorTransitionMaskImage = UIImage(named: "close")
navigationItem?.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
Then use it in the view controllers as follows:
addCustomizedBackBtn(navigationController: self.navigationController, navigationItem: self.navigationItem)
Upvotes: 7
Reputation: 500
You can change the title to @"" of the current ViewController on viewWillDisappear, and when it's about to show again re-set the title to whatever it was before.
-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.title = @"Previous Title";
}
-(void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
self.title = @"";
}
Upvotes: 1
Reputation: 7224
It's actually pretty easy, here is what I do:
Objective C
// Set this in every view controller so that the back button displays back instead of the root view controller name
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
Swift 2
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)
Swift 3
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
Put this line in the view controller that is pushing on to the stack (the previous view controller). The newly pushed view controller back button will now show whatever you put for initWithTitle, which in this case is an empty string.
Upvotes: 319
Reputation: 3318
Just use an image!
OBJ-C:
- (void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"Icon-Back"]
style:UIBarButtonItemStylePlain
target:self.navigationController
action:@selector(popViewControllerAnimated:)];
self.navigationItem.leftBarButtonItem = backButton;
}
SWIFT 4:
let backBTN = UIBarButtonItem(image: UIImage(named: "Back"),
style: .plain,
target: navigationController,
action: #selector(UINavigationController.popViewController(animated:)))
navigationItem.leftBarButtonItem = backBTN
navigationController?.interactivePopGestureRecognizer?.delegate = self
Icon-Back.png
Upvotes: 78
Reputation: 8458
I'm written an extension to make this easier:
extension UIViewController {
/// Convenience for setting the back button, which will be used on any view controller that this one pushes onto the stack
@objc var backButtonTitle: String? {
get {
return navigationItem.backBarButtonItem?.title
}
set {
if let existingBackBarButtonItem = navigationItem.backBarButtonItem {
existingBackBarButtonItem.title = newValue
}
else {
let newNavigationItem = UIBarButtonItem(title: newValue, style:.plain, target: nil, action: nil)
navigationItem.backBarButtonItem = newNavigationItem
}
}
}
}
Upvotes: 1
Reputation: 9
Set back button item title as empty String.
[self.navigationController.navigationBar.backItem setTitle:@""];
Upvotes: 0
Reputation: 9778
I found an easy way to make my back button with iOS single arrow.
Let's supouse that you have a navigation controller going to ViewA from ViewB. In IB, select ViewA's navigation bar, you should see these options: Title, Prompt and Back Button.
ViewA navigate bar options
The trick is choose your destiny view controller back button title (ViewB) in the options of previous view controller (View A). If you don't fill the option "Back Button", iOS will put the title "Back" automatically, with previous view controller's title. So, you need to fill this option with a single space.
Fill space in "Back Button" option
The Result:
Upvotes: 196
Reputation: 535
You may place that category in AppDelegate.m file.
to removes text from all default back buttons in UINavigation. Only the arrow "<" or set custom image if you need.
Objective-c:
...
@end
@implementation UINavigationItem (Extension) - (UIBarButtonItem *)backBarButtonItem { return [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil]; } @end
Upvotes: 0
Reputation: 31
Check this answer
How to change the UINavigationController back button name?
set title
text to string
with one blank space as below
title = " "
Don't have enough reputation to add comments :)
Upvotes: 2
Reputation: 5646
Upvotes: 1
Reputation: 1948
This is how I do it and the simplest, works and most clear way to do it.
This works if embed on Navigation Controller
Swift 3
In viewDidLoad
I add this to the View Controller you want the back button to be just arrow.
if let topItem = self.navigationController?.navigationBar.topItem {
topItem.backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: nil, action: nil)
}
The difference of this to @Kyle Begeman's answer is that you call this on the view controller that you want the back button to be just arrow, not on the pushing stack view controller.
Upvotes: 13
Reputation: 422
If you set the tintColor Of NavigationBar,add a custom back button image without title that tint color will reflect the image color. Please follow this apple documentaion link.
UINavigationItem *navItem = [[UINavigationItem alloc] init];
navBar.tintColor = self.tintColor;
UIImage *myImage = [UIImage imageNamed:@"left_arrow.png"];
myImage = [myImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIBarButtonItem *leftButton = [[UIBarButtonItem alloc] initWithImage:myImage style:UIBarButtonItemStylePlain target:self action:@selector(cancelButtonFunction:)];
navItem.leftBarButtonItem = leftButton;
navBar.items = @[ navItem ];
Upvotes: 1
Reputation: 131
If you have two ViewController(FirstVC, SecondVC) Embed in Navigation Controller, and you want there is only back arrow in SecondVC.
You can try this In FirstVC's ViewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)
}
Then when you push into SecondVC, you'll see the there is only back arrow
Upvotes: 1
Reputation: 977
The only way that worked for me was:
navigationController?.navigationBar.backItem?.title = ""
UPDATE:
When I changed the segue animation flag to true (It was false before), the only way that worked for me was:
navigationController?.navigationBar.topItem?.title = ""
Upvotes: 1
Reputation: 31
All the answers do not solve the issue. It is not acceptable to set back button title in every view controller and adding offset to the title still makes next View Controller title shift to the right.
Here is the method using method swizzling, just create new extension to UINavigationItem
import UIKit
extension UINavigationItem {
public override class func initialize() {
struct Static {
static var token: dispatch_once_t = 0
}
// make sure this isn't a subclass
if self !== UINavigationItem.self {
return
}
dispatch_once(&Static.token) {
let originalSelector = Selector("backBarButtonItem")
let swizzledSelector = #selector(UINavigationItem.noTitleBackBarButtonItem)
let originalMethod = class_getInstanceMethod(self, originalSelector)
let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)
let didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))
if didAddMethod {
class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
} else {
method_exchangeImplementations(originalMethod, swizzledMethod)
}
}
}
// MARK: - Method Swizzling
struct AssociatedKeys {
static var ArrowBackButtonKey = "noTitleArrowBackButtonKey"
}
func noTitleBackBarButtonItem() -> UIBarButtonItem? {
if let item = self.noTitleBackBarButtonItem() {
return item
}
if let item = objc_getAssociatedObject(self, &AssociatedKeys.ArrowBackButtonKey) as? UIBarButtonItem {
return item
} else {
let newItem = UIBarButtonItem(title: " ", style: UIBarButtonItemStyle.Plain, target: nil, action: nil)
objc_setAssociatedObject(self, &AssociatedKeys.ArrowBackButtonKey, newItem as UIBarButtonItem?, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
return newItem
}
}
}
Upvotes: 3
Reputation: 86
Set back title empty
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStyleDone target:self action:@selector(handleBack:)];
[backButton setTintColor:Color_WHITE];
[self.navigationItem setBackBarButtonItem:backButton];
Change back image
UIImage *backImg = [[UIImage imageNamed:@"ic_back_white"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
[UINavigationBar appearance].backIndicatorImage = backImg;
[UINavigationBar appearance].backIndicatorTransitionMaskImage = backImg;
Upvotes: 2
Reputation: 3854
This works, but it will remove the title of the previous item, even if you pop back to it:
self.navigationController.navigationBar.topItem.title = @"";
Just set this property on viewDidLoad
of the pushed View Controller.
Upvotes: 22
Reputation: 833
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
// Custom initialization
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
}
return self;
}
Just like Kyle Begeman does, you add the code above at your root view controller. All the sub view controller will be applied. Additionally, adding this in initWithCoder: method, you can apply the style for root view controllers in xib, storyboard or code based approaches.
Upvotes: 0
Reputation: 540
Nothing much you need to do. You can achieve the same through storyboard itself.
Just go the root Navigation controller and give a space. Remember not to the controller you wanted the back button without title, but to the root navigation controller.
Upvotes: 26
Reputation: 3222
You can subclass UINavigationController, set itself as the delegate, and set the backBarButtonItem in the delegate method navigationController:willShowViewController:animated:
@interface Custom_NavigationController : UINavigationController <UINavigationControllerDelegate>
@end
@implementation Custom_NavigationController
- (void)viewDidLoad
{
[super viewDidLoad];
self.delegate = self;
}
#pragma mark - UINavigationControllerDelegate
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
viewController.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStylePlain target:nil action:nil];
}
@end
Upvotes: 2
Reputation: 7261
EDIT: 2014-04-09: As I gained reputations, I feel sorry because I don't use this trick any more. I recommend Kyle's answer. Also notice that the self
of self.navigationItem.backBarButtonItem
isn't the view controller the back button is displayed, but the previous view controller to be went back.
If you don't need to have title text for the previous view controller, just fill the title with a blank string;
self.navigationItem.title = @"";
[self.navigationController pushViewController:viewController animated:YES];
This will prevent showing "back" with chevron on the pushed view controller.
EDIT: Even you use non-blank title text, setting the title of the previous view controller in viewWillAppear:
works except the title can flicker in a blink when view controller popped. I think "The twitter app" seems to do more subtle hack to avoid the flicker.
Upvotes: 21
Reputation: 2220
Target:
customizing all back button on UINavigationBar
to an white icon
Steps: 1. in "didFinishLaunchingWithOptions" method of AppDelete:
UIImage *backBtnIcon = [UIImage imageNamed:@"navBackBtn"];
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
[UINavigationBar appearance].tintColor = [UIColor whiteColor];
[UINavigationBar appearance].backIndicatorImage = backBtnIcon;
[UINavigationBar appearance].backIndicatorTransitionMaskImage = backBtnIcon;
}else{
UIImage *backButtonImage = [backBtnIcon resizableImageWithCapInsets:UIEdgeInsetsMake(0, backBtnIcon.size.width - 1, 0, 0)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:backButtonImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackButtonTitlePositionAdjustment:UIOffsetMake(0, -backButtonImage.size.height*2) forBarMetrics:UIBarMetricsDefault];
}
2.in the viewDidLoad
method of the common super ViewController
class:
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
UIBarButtonItem *backItem = [[UIBarButtonItem alloc] initWithTitle:@""
style:UIBarButtonItemStylePlain
target:nil
action:nil];
[self.navigationItem setBackBarButtonItem:backItem];
}else{
//do nothing
}
Upvotes: 7
Reputation: 487
// add left bar button item
try this code:
- (void)viewDidLoad
{
[super viewDidLoad];
UIImage* image_back = [UIImage imageNamed:@"your_leftarrowImage.png"];
CGRect backframe = CGRectMake(250, 9, 15,21);
UIButton *backbutton = [[UIButton alloc] initWithFrame:backframe];
[backbutton setBackgroundImage:image_back forState:UIControlStateNormal];
[backbutton addTarget:self action:@selector(Btn_back:)
forControlEvents:UIControlEventTouchUpInside];
[backbutton setShowsTouchWhenHighlighted:YES];
UIBarButtonItem *backbarbutton =[[UIBarButtonItem alloc] initWithCustomView:backbutton];
self.navigationItem.leftBarButtonItem=backbarbutton;
[backbutton release];
}
-(IBAction)Btn_back:(id)sender
{
[self.navigationController popViewControllerAnimated:YES];
}
Upvotes: 3
Reputation: 1158
While Kyle Begeman's answer totally does the trick, it is quite annoying to have this code in every view controller possible. I ended up with a simple UINavigationItem
category. Beware, here be dragons! Sorry, I mean, swizzling:
#import <objc/runtime.h>
@implementation UINavigationItem (ArrowBackButton)
static char kArrowBackButtonKey;
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Method m1 = class_getInstanceMethod(self, @selector(backBarButtonItem));
Method m2 = class_getInstanceMethod(self, @selector(arrowBackButton_backBarButtonItem));
method_exchangeImplementations(m1, m2);
});
}
- (UIBarButtonItem *)arrowBackButton_backBarButtonItem {
UIBarButtonItem *item = [self arrowBackButton_backBarButtonItem];
if (item) {
return item;
}
item = objc_getAssociatedObject(self, &kArrowBackButtonKey);
if (!item) {
item = [[UIBarButtonItem alloc] initWithTitle:@"" style:UIBarButtonItemStyleBordered target:nil action:NULL];
objc_setAssociatedObject(self, &kArrowBackButtonKey, item, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return item;
}
@end
Upvotes: 22
Reputation: 39384
This did the trick for me
[[UIBarButtonItem appearance]
setBackButtonTitlePositionAdjustment:UIOffsetMake(-1000, -1000)
forBarMetrics:UIBarMetricsDefault];
All the best
Upvotes: -1
Reputation: 4879
To add to Thomas C's answer above, sometimes putting a single space doesn't work and you have to keep adding spaces.
You'll know you succeeded when you see "Bar Button Item - " under the "Navigation Item". That's in the Document Outline (Editor->Show Document Outline). Once you see the above picture, you can delete a few spaces and see if it still works.
Upvotes: 0
Reputation: 21
I applied the following code in viewDidLoad and it works:
// this will set the back button title
self.navigationController.navigationBar.topItem.title = @"Test";
// this line set the back button and default icon color
//[[self.navigationController.navigationBar.subviews lastObject] setTintColor:[UIColor blackColor]];
this line change the back default icon to your custom icon
[[self.navigationController.navigationBar.subviews lastObject] setTintColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"menuicon"]]];
Just to update I use Vector Icon
Upvotes: 2
Reputation: 9397
Create a UILabel
with the title you want for your root view controller and assign it to the view controller's navigationItem.titleView
.
Now set the title to an empty string and the next view controller you push will have a back button without text.
self.navigationItem.titleView = titleLabel; //Assuming you've created titleLabel above
self.title = @"";
Upvotes: 3
Reputation: 584
you can use this. This works perfectly for me by just adding a UIButton
as a custumview for the UIBarButtonItem
.
Try the Below Code
self.navigationItem.leftBarButtonItem=[self backButton];
- (UIBarButtonItem *)backButton
{
UIImage *image = [UIImage imageNamed:@"back-btn.png"];
CGRect buttonFrame = CGRectMake(0, 0, image.size.width, image.size.height);
UIButton *button = [[UIButton alloc] initWithFrame:buttonFrame];
[button addTarget:self action:@selector(backButtonPressed) forControlEvents:UIControlEventTouchUpInside];
[button setImage:image forState:UIControlStateNormal];
UIBarButtonItem *item= [[UIBarButtonItem alloc] initWithCustomView:button];
return item;
}
Upvotes: 3