hidesBackButton works but backbarbuttonitem setAction not working - ios

I'd like to change action of my backbutton in one of my ViewController. Instead of going back to the precedent view, I want to perform an action in the same ViewController.
self.navigationItem.hidesBackButton=NO;
hides the BackButton but
[self.navigationController.navigationItem.backBarButtonItem setAction:#selector(performBackNav:)];
and
[self.navigationItem.backBarButtonItem setAction:#selector(performBackNav:)];
do the same as before (going back to precedent ViewController). Nothing changes.
-(void)performBackNav:(id)sender {
//Actions
[self.navigationController popViewControllerAnimated:NO];
}
Any ideas to modify backbarbuttonitem's action ?

Instead of overriding the action method of default back button create a custom button. this is one of the way Try this
{
UIButton *urButton = [UIButton buttonWithType:UIButtonTypeCustom];
urButton.frame = urRequiredFrame;
[urButton setImage:urImage forState:UIControlStateNormal];
[urButton addTarget:self action:#selector(performBackNav:)
forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *doneButton =[[UIBarButtonItem alloc] initWithCustomView:urButton];
self.navigationItem.leftBarButtonItem=doneButton;
}
-(void)performBackNav:(id)sender {
//Actions
[self.navigationController popViewControllerAnimated:NO];
}

Related

Back button without using navigation controller in IOS

I haven't embedd navigation controller with my view controller. Now i'm using a code to go back to home screen to with the use of back button but there nothing appears, i don't know why. I don't want to use navigation controller in my vc. This is the code,
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"car_marker.png"]
style:UIBarButtonItemStylePlain
target:self.navigationController
action:#selector(popViewControllerAnimated:)];
self.navigationItem.leftBarButtonItem = backButton;
It should look like this only,
You will need to change your approach because you cannot pop without a navigation controller.
You should embed your viewcontroller into navigation controller and then you can hide with [[self navigationController] setNavigationBarHidden:YES animated:YES]; and then you can add any kind of custom button to perform pop action.
For adding a custom back button to your view
- (void)addCustomBackButtonToView
{
UIButton *backButton = [[UIButton alloc] initWithFrame: CGRectMake(20, 20, 44.0f, 30.0f)];
[backButton setImage:[UIImage imageNamed:#"back.png"] forState:UIControlStateNormal];
[backButton addTarget:self action:#selector(popVC) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:backButton];
}
- (void) popVC{
[self.navigationController popViewControllerAnimated:YES];
}
You can hide your navigation controller by below code self.navigationController.navigationBar.isHidden = true
and use swipegesture option to move back, even though you have to use navigation controller,#iPeter has a valid point.
1) Add two ViewControllers make first as initial controller(entry point).
2) Add view on both ViewController with size you wish to have.
3) Add buttons on both views as subviews.
4) create segue from firstButton ->(use show) -> second controller.
5) From second ->(use show) -> first controller.
see the image below-:
This is not preferred way of doing pop/push. You must use Navigation Controller(that works like a stack for controllers you push) that will provide you default Back button or you can create custom .
You can not push or pop view controllers as you are not using the Navigation controller. Try using Present & dismiss controller which can called from any controller Instace.
Step 1 : Present to " Controller which is shown with no navigation bar but back button"
[self presentViewController:#"<ViewControllerToBePresented>" animated:NO completion:nil];
Step 2: add backBatton in ViewDidLoad
-(void)addBack{
UIButton *backBtn = [[UIButton alloc] initWithFrame: CGRectMake(20.0f, 20.0f, 50.0f, 30.0f)];
[backBtn setTitle:#"back" forState:UIControlStateNormal];
[backBtn addTarget:self action:#selector(dismissViewController) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:backBtn];
}
Step 3: Dismisscontroller to go back to previous scene
-(void) dismissViewController{
[self dismissViewControllerAnimated:NO completion:nil];
}

self.navigationItem.backBarButtonItem cannot be set

I have a TableViewController named TVC and a cell in it. When I clicked on cell, TableViewController will push a new ViewController (VC) into its navigation controller. In this case, I set the [self.navigationItem.backBarButtonItem setTitle:#" "] in the viewDidLoad function of the TVC. But in the new pushed ViewController VC, the back button still has the "back" text. Can anyone explain this?
BTW, the TableViewController TVC is also pushed by another view controller VC2. I set the same function [self.navigationItem.backBarButtonItem setTitle:#" "] in the viewDidLoad function of the VC2 and the back button text displayed in the TVC is correctly hidden.
What Bimala and Ted pointed are two ways of approaching the issue. The former is to set a custom BackButtonItem and the latter is to simply use the default BackButton. But setting the title of the screen to "" may not always be acceptable. So u can choose to do the same in ViewWillDisappear method.
OBJ C:
-(void) viewWillDisappear:(BOOL)animated{
self.navigationItem.title = #"";
[super viewWillDisappear:animated];
}
SWIFT:
override func viewWillDisappear(animated: Bool) {
self.title = ""
super.viewWillDisappear(true)
}
Also you can set the title back in ViewWillappear
OBJ C:
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.navigationItem.title = #"your title";
}
SWIFT:
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(true)
self.title = "your title"
}
That's because the back button takes the title of the previous view controller. When none set it defaults to back. So set the name of the TableViewController to an empty string as follows:
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.title = ""
}
Its my example:
UIView *leftView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
[leftView setBackgroundColor:[UIColor clearColor]];
UIButton *leftViewButton = [UIButton buttonWithType:UIButtonTypeCustom];
[leftViewButton setFrame:CGRectMake(0, 0, 30, 30)];
[leftView addSubview:leftViewButton];
[leftViewButton setImage:[UIImage imageNamed:#"NavigationBarButtonBackDefault"] forState:UIControlStateNormal];
[leftViewButton setImage:[UIImage imageNamed:#"NavigationBarButtonBackPressed"] forState:UIControlStateHighlighted];
UIBarButtonItem *barButtonItemLeft = [[UIBarButtonItem alloc] initWithCustomView:leftView];
self.navigationItem.leftBarButtonItem = barButtonItemLeft;
from documentation:
If the title of your back button is too long to fit in the available space on the navigation bar, the navigation bar may substitute the string “Back” in place of the button’s original title. The navigation bar does this only if the back button is provided by the previous view controller. If the new top-level view controller has a custom left bar button item—an object in the leftBarButtonItems or leftBarButtonItem property of its navigation item—the navigation bar does not change the button title.
If you just want to hide Back button then try:
self.navigationItem.hidesBackButton = YES;
or
self.navigationController.navigationBar.topItem.hidesBackButton = YES;
If you want to set custom Back button then use:
UIBarButtonItem *barButtonItem = [ [UIBarButtonItem alloc] initWithTitle: #"Custom"
style: UIBarButtonItemStylePlain
target: nil action: nil];
self.navigationController.navigationBar.topItem.backBarButtonItem = barButtonItem;

How to stop UINavigationBar default back button animation using storyboard?

I am using storyboard in my app where I have to navigate to another view controller without animation.I am successfully doing it using the custom segue.But I when I come back to the previous view controller then by using navigation bar default back button then it is animating while coming backward.So going forward it is not animating and going backward it is animating.I want to stop the default animation of the back button.
Custom Seague
// PushNoAnimationSegue.h
#interface PushNoAnimationSegue : UIStoryboardSegue
#end
// PushNoAnimationSegue.m
#implementation PushNoAnimationSegue
-(void) perform{
[[[self sourceViewController] navigationController] pushViewController:[self destinationViewController] animated:NO];
}
#end
Using this code I am successfully going to the next view controller without animation since -(void) perform is called automatically in the forward direction.When I come back it is not called.So please suggest me if there is anything wrong with the implementation or I should go with some other method.
hope this will help
1.custom button on navigation bar
UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(x,y,width,height)];
[btn setImage:[UIImage imageNamed:#"some_image.png"] forState:UIControlStateNormal];
[btn addTarget:self action:#selector(popViewController) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *backButtonItem = [[UIBarButtonItem alloc] initWithCustomView:btn];
self.navigationItem.leftBarButtonItem =backButtonItem;
and then
void popViewController()
{
[self.navigationController popViewControllerAnimated:NO];
}
If you use NavigationController then use this
[self.navigationController popViewControllerAnimated:NO];
Or
[self dismissViewControllerAnimated:NO completion:nil];

How to call some code if users press back button

In UINavigationController?
For example, say I want to make sure that the UINavigationController is not animating when user press the back button.
If you aren't intending to intercept the back button tap itself but instead the act of the current view controller disappearing, you can use:
- (void)viewWillDisappear:(BOOL)animated {
if (self.isMovingFromParentViewController) {
// handle back button press
}
}
If you are sure you want to do the back button, you can create your own custom UIBarButtonItem and set it to the current controller's leftBarButtonItem. Be sure to call [self.navigationController popViewControllerAnimated:YES] after you have finished doing your own logic.
Add below code in ViewDidLoad of your application :
UIButton *btnBack = [UIButton buttonWithType:UIButtonTypeCustom];
[btnBack setFrame:CGRectMake(0.0f, 0.0f, 55.0f, 35.0f)];
[btnBack addTarget:self action:#selector(backClicked:) forControlEvents:UIControlEventTouchUpInside];
[btnBack setImage:[UIImage imageNamed:#"back.png"] forState:UIControlStateNormal];
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithCustomView:btnBack];
self.navigationItem.leftBarButtonItem = backButton;
This create a custom Back button. "Back.png" is image same as that of OS.
Add below code as function. This one pops to RootViewcontroller.
- (void) backClicked:(id)sender {
// perform certain task
// If task is completed then call below LOC
[self.navigationController popToRootViewControllerAnimated:YES]; }

Navigationbar title and back button name are same?

I created one title for navigationbar in my storyboard project ,but when I moved to next viewcontroller the back button shows the same name as my previous navigationbar(Main navigationbar) title.? Can i set separate title and back button names?
I tried following code but its not working ? why?
self.navigationItem.title=#"Recent Books";
self.navigationItem.backBarButtonItem.title=#"Back";
According to UINavigationItem Class Reference
"When this navigation item is immediately below the top item in the
stack, the navigation controller derives the back button for the
navigation bar from this navigation item. [...] If you want to specify
a custom image or title for the back button, you can assign a custom
bar button item (with your custom title or image) to this property
instead."
So try this in your first VC from where you are pushing other VC
self.navigationItem.title=#"Recent Books";
UIBarButtonItem *backButton = [[UIBarButtonItem alloc]
initWithTitle:#"Back"
style:UIBarButtonItemStylePlain
target:nil
action:nil];
self.navigationItem.backBarButtonItem=backButton;
Let's say you are pushing your viewcontroller A -> B
In viewcontroller A try adding this code in viewDidLoad method
UIBarButtonItem *btn_Back = [[UIBarButtonItem alloc] initWithTitle:#"Back"
style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.backBarButtonItem=btn_Back;
So you will see your "Back" button in viewcontroller B
The following should solve your problem
-(void)viewDidAppear:(BOOL)animated
{
self.navigationController.navigationBar.backItem.title = #"back";
}
You can also use this Objective-C syntax
[[self.navigationController.navigationBar backItem] setTitle:#"back"];
Just do it in this way , one of the easiest way I did find till now :
Create a custom back button and add it into the Navigation Bar left button item property :
- (void)viewDidLoad
{
UIButton *backBtn = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *backBtnImage = [UIImage imageNamed:#"Backnavigation.png"] ; // Here set the back button image
[backBtn setBackgroundImage:backBtnImage forState:UIControlStateNormal];
[backBtn addTarget:self action:#selector(handleBack:) forControlEvents:UIControlEventTouchUpInside];
backBtn.frame = CGRectMake(0, 0, 24, 24);
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithCustomView:backBtn] ;
self.navigationItem.leftBarButtonItem = backButton;
}
//Handle the Back Button Event
- (void) handleBack:(id)sender
{
// do your custom handler code here
[self.navigationController popViewControllerAnimated:YES];
}
Also, doing this way, you don't need to change the title of NavigationBar every-time.
Here is the Back Button for your reference :
You can use the below code in the viewWillAppear(animated:Bool) method of the view controller in which you want to set the backButton title of you choice :
self.navigationController?.navigationBar.topItem?.backBarButtonItem = UIBarButtonItem(title: "Back Title", style: .plain, target: nil, action: nil)

Resources