How to get the method of backBarButtonItem of navigationItem? - ios

I have add the navigationItem.backBarButtonItem when turn to the new page like the following code , but I want to add a Timer for change some image before turn back to the first by backBarButtonItem.
UIViewController *ReconnectView = [[AITReconnectView alloc] initWithNibName:#"AITReconnectView" bundle:nil] ;
ReconnectView.edgesForExtendedLayout = UIRectEdgeNone;
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"Back", nil) style:UIBarButtonItemStyleBordered target:nil action:nil];
[self.navigationController pushViewController:ReconnectView animated:YES];
For example : When I click the backBarButtonItem , it will run the Timer for 3 second. And then turn back to the first view.
I have search for some information , but it only overwrite the new method for backBarButtonItem.
How to add a Timer in method of backBarButtonItem but retain the original method of backBarButtonItem ?
Thanks in advance.

There are two ways:
Create your own back button (similar like native) and selector method and assign it to button:
UIBarButtonItem *addButton = [[[UIBarButtonItem alloc] initWithTitle:#"BackToVcA"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(addAction:)] autorelease];
self.navigationItem.rightBarButtonItem = addButton;
Use UIViewController life cycle method, viewWillDisappear or viewDidDisappear.
Hope this is what you're looking for.

If you want to delay the transition to the first view by 3 seconds,
Just add,
[NSThread sleepForTimeInterval:3.0]; to viewWillDisappearmethod of the second view.
If you want to execute method invocation in objective C, then
[self performSelector:#selector(methodName) withObject:self afterDelay:3.0];
should work fine. Share code for some more information.

Related

iOS action of navigation bar back button not working [duplicate]

Trying to customize my back button in a drilldown navigation controller.
On my one view controller I have an Add button where the code programatically generates a new UIViewController:
- (void)add:(id)sender
{
MyAddViewController *addController = [[MyAddViewController alloc] initWithNibName:#"MyAddViewController" bundle:nil];
[self.navigationController pushViewController:addController animated:YES];
[addController release];
}
This works and when I click the add button it drills down into the new view. Inside the viewDidLoad method of MyAddViewController.m I have:
self.navigationItem.backBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:nil action:nil] autorelease];
But this isn't working. The back button in the navigation controller remains the title of the previous view's controller on the stack. It seems that line does nothing. Did I miss something?
Thanks
self.navigationItem.backBarButtonItem is for the back button that appears on the view pushed by the view controller. So you need to move that line to the previous view controller.
This will only work on each child after the viewController that has self.navigationItem.backBarButtonItem.
You're confusing the backBarButtonItem and the leftBarButtonItem. From the UINavigationItem docs on backBarButtonItem:
When this item is the back item of the
navigation bar—when it is the next
item below the top item—it may be
represented as a back button on the
navigation bar. Use this property to
specify the back button. The target
and action of the back bar button item
you set should be nil. The default
value is a bar button item displaying
the navigation item’s title.
So, if you were to change:
self.navigationItem.backBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:nil action:nil] autorelease];
To:
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:nil action:nil] autorelease];
I believe you would get the desired effect.
You can't replace the backBarButtonItem, but you can use the leftBarButtonItem to override it. But to get the new button to perform operate the same as the back button, you do need to set the target and action of the new button something like:
- (void)dismissMyView {
[self.navigationController popViewControllerAnimated:YES];
}
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]
initWithTitle:#"Quit" style: UIBarButtonItemStyleBordered
target:self action:#selector(dismissMyView)];
}
If ViewController A push ViewController B meanwhile we want to set the back bar button tittle, we should set "self.navigationItem.backBarButtonItem = ..".if it was set in ViewController B, it will not work as we want.

how to use back button with presentViewController?

Here is my code for calling a new view controller that is wrapped in a UINavigationController. I want a simple back button on the restaurantResults controller. My selector does not seem to work. I've tried using pop commands. Will those work since I am using presentViewController and not any sort of push?
Pretty sure my selector is wrong right now because it says self.navigationController, which can't possibly be right.
Here is where I call the new view controllers and set up the back button:
- (void)searchBarSearchButtonClicked:(UISearchBar *)foodNearSearchBar
{
restaurantsViewController *restaurantResults = [[restaurantsViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:restaurantResults];
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Back"
style:UIBarButtonItemStyleBordered
target:nil
action:#selector(backPressed:)];
restaurantResults.navigationItem.leftBarButtonItem = backButton;
[self presentViewController:navController animated:YES completion:Nil];
}
Here is my selector:
-(void)backPressed: (id)sender
{
[self.navigationController popViewControllerAnimated: YES]; // or popToRoot... if required.
}
I also tried:
- (void)backPressed:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
};
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Back"
style:UIBarButtonItemStyleBordered
target:nil
ction:#selector(backPressed:)];
restaurantResults.navigationItem.leftBarButtonItem = backButton;
these code should be used on the restaurantsViewController;
the target is self.
If you are using a UINavigationController and you want the default iOS back button, you do not need to set it programatically. There is literally nothing to add, it's built in by default.
By pushing the UIViewController into the navigation controller, it'll be in the navigation controller stack of controllers, and iOS will therefore add a navigation bar, and a back button when you dig into the navigation stack.
If its not working, check the following :
That the controller you're pushing from is the root of the UINavigationController. You can set this by code or in storyboard. (you're OK)
That you're pushing from the navigation controller and not the viewcontroller. Essentially you have to do navigationcontroller.push() and not self.push(), otherwise it just won't work. (depends what self is here, but I'm pretty sure your mistake is here)
I see that you're using presentViewController which is for modals, its fine if that is your intent, but if you want a navigation stack, why not embed self in a navigation controller in the first place, hide its navigation bar, and then simply push your next controller onto it.
That way you dont have to manually create that back button, and let iOS deal with everything.
If you must do it that way, you can only "dismiss" when you "present", and "pop" when you "push". But I don't have enough information to know why yours does not work. Try a few things and give us more feedback. But from what I see you're going for a more complicated solution than necessary.
Also I would really start with a simple button that says "close" and see if it works that way before trying to embed it in a bar with an item. That way you tackle one problem, and one new concept at a time
//This works - Just did it
//You can create back button in the view you want to see back button -
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Login"
style:UIBarButtonItemStylePlain
target:self
action:#selector(backPressed:)];
self.navigationItem.leftBarButtonItem = backButton;
[self.navigationItem setHidesBackButton:NO];
// And just do dismiss the view controller in the viewcontroller where the back button is - as below-
- (void)backPressed:(id)sender
{
[self dismissViewControllerAnimated:YES completion:nil];
};

Back button pressed, losing my custom UIToolBar when i pop the view controller off the stack

I hope everyone is having a great day so far.
I'm running into a problem with my app that I need some help figuring out. I have a view controller (lets call "A") with a custom toolbar which works nicely.
When I push a view controller (lets call it "locationsController") from view controller "A" ...
[self.navigationController pushViewController:self.locationsController animated:YES];
...and I press the back button on the locationsController which closes like this...
[self.navigationController popViewControllerAnimated:YES];
I lose my custom toolbar in view controller "A" when locationController is popped. How do I fix it so I can intercept and call my buildtoolbar method?
Also, the locationsController can be pushed/popped from one other view controller so I'll need to determine which view controller is popping locationsController and either fire the buildtoolbar method or do nothing since the other view controller doesn't have a toolbar.
view controller "A" is a XIB while locationsController is defined in the storyboard.
the XIB does not Have a toolbar in the view/layout thingy.
toolbar code called from viewDidLoad [self buildToolbar]...
-(void) buildToolbar{
blah blah blah
self.navigationController.toolbarHidden = NO;
UIBarButtonItem *flexableItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *refresh = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:#selector(refresh:)];
UIBarButtonItem *comments = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"Comments-selected.png"] style:UIBarButtonItemStyleDone target:self action:#selector(cameraButtonTapped:)];
UIBarButtonItem *pin = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"Pin-straight_60wide.png"] style:UIBarButtonItemStyleDone target:self action:#selector(pinBarButtonItemPressed:)];
NSArray *items = [NSArray arrayWithObjects:customBarButtonItem_right, flexableItem, comments, flexableItem, pin, flexableItem, refresh, nil];
// [self.navigationController.toolbar setItems:items animated:YES];
self.toolbarItems = items;
}
Thanks in advance!
I moved my call to toolbarSetup from viewDidLoad to viewWillAppear. Apparently the 2nd VC's viewDidLoad doesn't fire when the top most VC is popped off the stack.
viewWillAppear fires followed by viewDidAppear, etc....

Adding a UIBarButtonItem programmatically to UINavigationBar

I dropped in a UINavigationBar in UIInterfaceBuilder. I present this view modally and just want a UIBackBarButton to return to my last view. I have an outlet and property to this UINavigationBar declared. I thought in my viewDidLoad method, I could create a UIBackButton like this:
UIBarButtonItem *backButton =
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonItemStyleBordered
target:self
action:#selector(goBack)];
self.navigationItem.backBarButtonItem = backButton;
[backButton release];
But I do not see my UIBackBarButtonItem on the UINavigationBar. I think I am doing something wrong here since I don't think my UINavigationBar knows I'm trying to add this UIBackBarButtonItem to it in this way. Would I have to do create an NSArray, put the button in it, and setItems for the NavigationBar instead?
I'm confused on how the navigationItem property works vs the setItems of the UINavigationBar as well. Any help would be appreciated. Thanks!
You are trying to set the Back Button Item in a modal view which doesn't add a backBarButtonItem. This what causes the Button (or any sort of back button for that matter) not to show. The backBarButtonItem is mainly for use with Pushed View Controllers which have a Back Button added from the parent (next item below) when you push a new view controller (top item). The Apple UINavigationItem Documentation says:
When this item is the back item of the navigation bar—when it is the next item below the top item—it may be represented as a back button on the navigation bar. Use this property to specify the back button. The target and action of the back bar button item you set should be nil. The default value is a bar button item displaying the navigation item’s title.
To get the Back Button on the left side like you wish, Try changing
self.navigationItem.backBarButtonItem = backButton;
to
self.navigationItem.leftBarButtonItem = backButton;
making a call such as this from a view controller
{
NextViewController* vcRootView = [[NextViewController alloc] initWithNibName:#"NextView" bundle:[NSBundle mainBundle]];
UINavigationController* navController = [[UINavigationController alloc] initWithRootViewController:vcRootView];
[vcRootView release];
[self.navigationController presentModalViewController:navController animated:YES];
[navController release];
}
will present NextViewController as a Modal view on the calling view and NextViewController will have a navigationController for it.
In The NextViewController implementation file all you need is this
- (void)viewDidLoad {
[super viewDidLoad];
UIBarButtonItem* backButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:self
action:#selector(barButtonBackPressed:)];
self.navigationItem.leftBarButtonItem = backButton;
[backButton release];
}
-(void)barButtonBackPressed:(id)sender{
[self dismissModalViewControllerAnimated:YES];
}
to have the back button to dismiss the modalview. Hope it helps.
Use below code snippet :
//Add button to NavigationController
UIBarButtonItem *backButton =
[[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#“back”, #"")
style:UIBarButtonItemStylePlain
target:self
action:#selector(goBack)];
self.navigationItem.leftBarButtonItem = backButton;
//Perform action on back Button
- (void) goBack { // Go back task over-here
}
Different style types available are :
UIBarButtonItemStylePlain, UIBarButtonItemStyleBordered, UIBarButtonItemStyleDone
You may use this setters without creation new UIBarButtonItem:
[self.navigationItem.leftBarButtonItem setAction:#selector(doBackButton:)];
[self.navigationItem.leftBarButtonItem setTarget:self];

How to change text on a back button

By default the back button uses as a text on it a title of a viewcontroller.
Can I change text on the back button without changing a title of a view controller?
I need this because I have a view controller which title is too long to display and in this case I would like to display just "Back" as a caption for back button.
I tried the following which didn't work:
self.navigationItem.leftBarButtonItem.title = #"Back";
Thanks.
Try
self.navigationItem.backBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:nil action:nil] autorelease];
I found that by looking at the backBarButtonItem docs in Apple's docs for UINavigationItem.
Marc W's approach worked great once I figured out which controller to apply it to: the one being re-titled, not the one on top. So if this is the navigation stack:
(bottom) ControllerA -> ControllerB (top)
...and you want to give a shorter title for ControllerA in the back-button displayed when ControllerB is on top, you apply the property change to ControllerA.
So it's more in the context of self.title, not like the other left/right-bar-button setters.
You can do it in the storyboard. Find the view controller you want to go back to (the one with the long title), select it's Navigation Item, and open the Attributes Inspector (Alt+Cmd+4), insert the custom Back Button title.
Thanks Marco... that helped me...
Here is what i did.
If you are using a tableView to navigate to different views... put the code:
self.navigationItem.backBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:nil action:nil] autorelease];
In your didSelectRowAtIndexPath method... of the first Controller... Controller A.
When you navigate to Controller B the button will have the title "Back".
The back button pulls its text from the title of the parent view controller.
In the parent view controller (the view controller that appears when you tap the back button), set its own title as the desired text on the back button.
For example, let's say we have a RootViewController class. When we click a cell in its table view, we push an instance of SecondViewController. We want the back button of the SecondViewController instance to read, "Home."
in the viewDidLoad method of RootViewController.m:
self.title = #"Home";
in the viewDidLoad method of SecondViewController.m:
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationItem.backBarButtonItem = backButton;
[backButton release];
If you want your back button to read, "Back," set the title of the parent view controller to #"Back";
This work better for me. Try :
self.navigationController.navigationBar.topItem.backBarButtonItem = [[UIBarButtonItem alloc]
initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:nil action:nil];
If you are using storyboard:
Open StoryBoard
In Document Outline window find ViewController to which you want to
return to
Click on Navigation Item of that ViewController
In Attributes explorer change Back Button value to your custom tile
That is it, enjoy...
And in MonoTouch the following works (in ViewDidLoad of the parent controller):
NavigationItem.BackBarButtonItem = new UIBarButtonItem( "Back", UIBarButtonItemStyle.Plain, null);
[self.navigationItem setBackBarButtonItem:[[UIBarButtonItem alloc]
initWithTitle:#"Back" style:UIBarButtonItemStyleBordered target:nil action:nil]];
This worked for me.
In your parent view controller, set the back button when view loads:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.navigationItem.backBarButtonItem =
[[UIBarButtonItem alloc] initWithTitle:#"title"
style:UIBarButtonItemStylePlain
target:nil
action:nil];
}
Notice that we don't need to include autorelease at the end with the latest iOS version.
Hope this helps!
[self.navigationController.navigationBar.backItem setTitle:#"back"];
It works for me. You can replace "back" with something else.
This one worked for me if you don't want to have a title!
self.navigationItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#" " style:UIBarButtonItemStylePlain target:nil action:nil];
self.navigationController.navigationBar.topItem.backBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStylePlain target:nil action:nil];
I finally knew why these answers did not work for me at first. I set the title in storyboard. When i set the title on code. it works!
self.navigationItem.title = #"Main Menu";
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#" " style:UIBarButtonItemStyleBordered target:nil action:nil];
[[self navigationItem] setBackBarButtonItem:backButton];
My solution was to set title when the view controller is pushed to navigation stack and reset it by use of delegate method before pushed vc closes:
So I put the title change in calling view controller when I push the other view controller like:
self.pushedVC = [self.storyboard instantiateViewControllerWithIdentifier:#"pushedVCIdentifier"];
self.pushedVC.delegate = self;
[self.navigationController pushViewController:self.pushedVC animated:YES];
self.title = #"Back";
and in delegate callback function (which I invoke in viewWillDissapear):
-(void)pushedVCWillClose:(PushedVC *)sender
{
self.title = #"Previous Title";
}
If you want not only to change the text of the Back button and remain the original left-arrow shape, but also to do something when user clicks the Back button, I recommend you to have a look around my "CustomNavigationController".
//You can achieve this by setting the title in the previous view controller as shown below
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
//Set Title for this view
self.navigationItem.title = "My Title"
}
override func viewWillDisappear(animated: Bool) {
super.viewWillAppear(animated)
//Set Title for back button in next view
self.navigationItem.title = "Back"
}
For to change back button title, refer below code
InformationVC *infoController=[[InformationVC alloc]init];[self.navigationController infoController animated:YES];
//Below code changed back button title on InformationVC page.
UIBarButtonItem *backBarButton = [[UIBarButtonItem alloc] initWithTitle:#"Information" style: UIBarButtonItemStylePlain target: nil action: nil];
self.navigationItem.backBarButtonItem = backBarButton;`enter code here`
In Swift5, the backBarButtom cannot be edited. Hence, we need to hide the backBarButtom first, then use a customised leftbarButtom to replace backBarButtom. Here is the detailed solution: https://stackoverflow.com/a/63868300/13939003
This worked for me:
self.navigationController.navigationBar.topItem.title = "Back"

Resources