How can i add method to UINavigationbar back button, so whenever I click that back button I need to check some values and show UIAlertView? Is there any option for this?
i tried this method but its working for me
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
//show alert
}
and also this method but both are not woking
-(void) viewWillDisappear:(BOOL)animated {
if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
// back button was pressed. We know this is true because self is no longer
// in the navigation stack.
NSLog(#"hi");
}
Yes you can
In viedDidLoad
UIBarButtonItem * backBtn = [[UIBarButtonItem alloc]initWithTitle:#"Back" style:UIBarButtonItemStyleBordered target:self action:#selector(goBackToAllPets:)];
self.navigationItem.leftBarButtonItem = backBtn;
write following function to check condition
-(void)goBackToAllPets:(id)sender
{
if(/*check condition*/)
{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:nil message:#"message" delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
alert.tag = 0;
[alert show];
}
else
{
[self.navigationController popViewControllerAnimated:YES];
}
}
Suppose you have two controllers - Controller1 and Controller2.
Controller2 is pushed from Controller1. So before pushing the Controller2 on the navigationController from Controller1
Controller2 *controller2 = [[[Controller2 alloc] init]autorelease];
self.navigationItem.hidesBackButton = YES;
Now, in the viewDidLoad: method of Controller2, add the following snippet
UIBarButtonItem *backBarButtonItem =[[[UIBarButtonItem alloc]initWithTitle:#"Back" style:UIBarButtonItemStyleBordered target:self action:#selector(goBackToAllPets:)]autorelease];
self.navigationItem.leftBarButtonItem = backBarButtonItem;
and in the backButtonClicked method, you can perform the checks you want to.
Related
I'm experimenting an issue with the numeric pad when popping the current UIViewController from the UINavigationController.
In my current UIViewController. I have a few UITextField and a "Save" button in the UINavigationBar. The expected behavior is as follows:
When the user taps "Save", the keyboard must hide and a network operation is performed. In its callback, an UIAlertView is shown. When user dismisses this UIAlertView, a notification raises and the current UIViewController performs
[self.navigationController popViewControllerAnimated:YES];
The thing is, if "Save" is pressed with the keyboard still showing, after performing the popViewControllerAnimated, the keyboard appears briefly and from left to right (as if it was visible in the previous UIViewController).
I've tried
[myTextField resignFirstResponder]
when user taps "Save", when user dismisses the UIAlertView, and even in the
viewWillDisappear
method. Some other answers suggest using
[self.view endEditing:YES];
but it doesn't work either.
If I could use the regular keyboard it would be trivial to override
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
to hide it when user taps "Return", "Done", etc. But being the numeric pad doesn't allow you to show that "finish" button.
I'd appreciate any help, thank you all for your time
Try this:
Set the text field delegate and its return type as Done and pad as numeric pad.
_textField.delegate = self;
_textField.keyboardType = UIKeyboardTypeDecimalPad;
[_textField setReturnKeyType:UIReturnKeyDone];
and now add the buttons to keyboard:
-(void)addButtonsToKeyboard
{
UIToolbar* keyboardDoneButtonView = [[UIToolbar alloc] init];
[keyboardDoneButtonView sizeToFit];
UIBarButtonItem* doneButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"Done", nil)
style:UIBarButtonItemStyleDone target:self
action:#selector(kbDoneAction:)];
UIBarButtonItem* seperatorItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem* cancelButton = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(#"Cancel", nil)
style:UIBarButtonItemStylePlain target:self
action:#selector(kbCancelAction:)];
[keyboardDoneButtonView setItems:[NSArray arrayWithObjects:cancelButton,seperatorItem, doneButton, nil]];
_textField.inputAccessoryView = keyboardDoneButtonView;
}
and to hide the keyboard:
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
and your Done action method is:
-(void)kbDoneAction:(id)sender
{
[_textField resignFirstResponder];
}
and Cancel action method is:
-(void)kbCancelAction:(id)sender
{
[_textField resignFirstResponder];
}
Try using the below code. It works fine for iOS 8 and below version
if (IS_OS_8_OR_LATER) {
UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:title message:msg preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *cancelAction = [UIAlertAction
actionWithTitle:B_title
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action)
{
[self.navigationController popViewControllerAnimated:YES];
}];
[alertVC addAction:cancelAction];
[self presentViewController:alertVC animated:YES completion:nil];
}
else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:msg delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[alert show];
}
}
I had a similar situation. I ended up delaying the popViewControllerAnimated a little longer than the keyboard animation duration (0.333 seconds).
I have a text editing view, and I would like to prompt the user before returning to the rootview when the text has been edited.
I have tried this so far.
self.navigationItem.leftBarButtonItem.title = #"Back";
self.navigationItem.leftBarButtonItem.tintColor = [UIColor grayColor];
-(void) viewWillDisappear:(BOOL)animated {
if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
// back button was pressed. We know this is true because self is no longer
// in the navigation stack.
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Confirm Submission" message:#"Current Job Sheet Incomplete\n Please Confirm Your Submission" delegate:self cancelButtonTitle:#"Submit" otherButtonTitles:#"Cancel", nil];
alert.tag = 1;
[alert show];
}
// [super viewWillDisappear:animated];
}
Although this shows the alert, it dose not stop the user from being pushed to the root view.
Add a custom button on leftBarButton
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style: UIBarButtonItemStylePlain target:self action:#selector(navigationBackBtnTap)];
self.navigationItem.leftBarButtonItem = backButton;
-(void)navigationBackBtnTap{
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"Confirm Submission" message:#"Current Job Sheet Incomplete\n Please Confirm Your Submission" delegate:self cancelButtonTitle:#"Submit" otherButtonTitles:#"Cancel", nil];
alert.tag = 1;
[alert show];
}
I want to add a pop up when someone pushes the "Back" button of my iOS App, to ask the user if he really wants to come back. Then, depending on the user's response, I would like to undo the action or proceed. I've tried to add the code in the viewWillDisappear function of my view and then write the proper delegate but it doesn't work, because it always change the view and then show the pop up. My code is:
-(void) viewWillDisappear:(BOOL)animated {
_animated = animated;
if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
UIAlertView *alert_undo = [[UIAlertView alloc] initWithTitle:#"UIAlertView"
message:#"You could be loosing information with this action. Do you want to proceed?"
delegate:self
cancelButtonTitle:#"Go back"
otherButtonTitles:#"Yes", nil];
[alert_undo show];
}
else [super viewWillDisappear:animated];
}
And the delegate implementation is:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if([title isEqualToString:#"Yes"])
{
[super viewWillDisappear:_animated];
}
}
This is not working at all. Does anybody now a better way to do it or what could be wrong?
Thank you very much,
Once -viewWillDisappear: is called, there's no stopping your viewController from disappearing.
You should ideally, override the navigationBar's back button and in it's method, display the alert (the rest being pretty much the same)
- (void)viewDidLoad
{
//...
UIBarButtonItem *bbtnBack = [[UIBarButtonItem alloc] initWithTitle:#"Back"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(goBack:)];
[self.navigationItem setBackBarButtonItem: bbtnBack];
}
- (void)goBack:(UIBarButtonItem *)sender
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Alert"
message:#"...Do you want to proceed?"
delegate:self
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
switch(buttonIndex) {
case 0: //"No" pressed
//do something?
break;
case 1: //"Yes" pressed
//here you pop the viewController
[self.navigationController popViewControllerAnimated:YES];
break;
}
}
NOTE: Don't forget to declare <UIAlertViewDelegate> in the .h file of this viewController
Thanks for your answer, #staticVoidMan! I finally used your code with some modifications. The back button cannot be modified so one should create a additional button and hid the standard one. The only problem is the style of the new "Back" button, which is not equal than the standard one. The final code is:
- (void)viewDidLoad
{
self.navigationItem.hidesBackButton = YES;
UIBarButtonItem *bbtnBack = [[UIBarButtonItem alloc] initWithTitle:#"Back"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(goBack:)];
self.navigationItem.leftBarButtonItem = bbtnBack;
}
- (void)goBack:(UIBarButtonItem *)sender
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Alert"
message:#"...Do you want to proceed?"
delegate:self
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
switch(buttonIndex) {
case 0: //"No" pressed
//do something?
break;
case 1: //"Yes" pressed
//here you pop the viewController
[self.navigationController popViewControllerAnimated:YES];
break;
}
}
i have a UI Image picker and its being shown inside a UI popoverController, i need a back button on UIimage picker navbar, so i can go back to previous popover.
let me explain in details.
1) i have a popup in which i tap and raise a notification, this notification is read on a view controller where i want this camera image picker popup. following is my code
-(void)registerNotificationForCameraSource
{
[[NSNotificationCenter defaultCenter]addObserver:self selector:#selector(mediaSourceCallback:) name:NOTIFICATION_FOR_CAMERA_SOURCE object:nil];
}
#pragma mark - Image picker Popover
-(void)mediaSourceCallback:(NSNotification *)notificationObj
{
capturedImages = [[NSMutableArray alloc] init];
pickerObj = [[UIImagePickerController alloc] init];
// [pickerObj setContentSizeForViewInPopover:CGSizeMake(320,480)];
pickerObj.delegate = self;
if ([notificationObj.object isEqualToString:#"UIImagePickerControllerSourceTypeCamera"])
{
pickerObj.sourceType = UIImagePickerControllerSourceTypeCamera;
pickerObj.modalPresentationStyle = UIModalPresentationFullScreen;
pickerObj.showsCameraControls = YES;
[self presentViewController:pickerObj animated:YES completion:nil];
}
else
{
[[UINavigationBar appearanceWhenContainedIn:[ApplicationDiscriptionPopupViewController class], nil] setBarTintColor:[UIColor redColor]];
pickerObj.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc]initWithTitle:#"Back" style:UIBarButtonItemStyleDone target:self action:#selector(imagePickerBackButtonTapped)];
[pickerObj.navigationController.navigationBar setBarTintColor:[UIColor redColor]];
[pickerObj setNavigationBarHidden:NO animated:YES];
//navigationControllerObj = [[UINavigationController alloc] initWithRootViewController:applicationDiscriptionPopupViewControllerObj];
_popoverControllerObj.popoverContentSize = CGSizeMake(320,480);
pickerObj.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[pickerObj presentedViewController];
[_popoverControllerObj setContentViewController:pickerObj animated:YES];
}
}
-(void)imagePickerBackButtonTapped
{
[pickerObj popToViewController:applicationDiscriptionPopupViewControllerObj animated:YES]; }
pickerObj is UI Image picker
applicationDiscriptionPopupViewControllerObj is view controller of my previous popover view. from where i came. now i wana go back to this view in the popup, when i tap on back button in nav bar.
but i dnt hav any nav bar. plz help
If you are adding a UIImagePickerController via presentViewController inside a UIViewController then you should see the default navigation bar. You should implement :
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
UINavigationItem *navBarTopItem;
// you cannot add a custom back button with native back button look like, so use image over
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:#"back_arrow.png"]
style:UIBarButtonItemStyleBordered
target:self
action:#selector(backAction)];
navBarTopItem.title = #"Albums"; // "Camera
navBarTopItem.leftBarButtonItem = backButton;
}
Add a back button action handler
-(void)backAction{
[self.navigationController popViewControllerAnimated:YES];
}
Hope that answer ur Q.
I am using an ABPeoplePickerNavigationController in my app and have overrode the navigation bar buttons to my own using UINavigationControllerDelegate.
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
navigationController.topViewController.searchDisplayController.searchBar.barStyle = UIBarStyleBlack;
navigationController.topViewController.navigationItem.leftBarButtonItem = nil;
navigationController.topViewController.navigationItem.rightBarButtonItem = nil;
UIBarButtonItem *cancelButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self
action:#selector(cancel:)];
navigationController.topViewController.navigationItem.leftBarButtonItem = cancelButtonItem;
UIBarButtonItem *addButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:#selector(addItem:)];
navigationController.topViewController.navigationItem.rightBarButtonItem = addButtonItem;
}
This works fine. However, when I use the search controller and exit out of it, my top right button suddenly changes to a Cancel button (see image below). How can I fix this? Thanks in advance.
OK, just figured out how to fix this. I just added a notification to see when the keyboard will be hidden and added the button back to the navigation bar.
1) Declare and synthesize the property mainNavigationController:
#property UINavigationController *mainNavigationController;
2) In (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated, add:
mainNavigationController = navigationController;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(onNotification:) name:UIKeyboardWillHideNotification object:nil];
3) Add the method onNotification:
-(void)onNotification:(NSNotification*)notification
{
UIBarButtonItem *addButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd
target:self
action:#selector(addItem:)];
mainNavigationController.topViewController.navigationItem.rightBarButtonItem = addButtonItem;
}
To fix this you have to implement the <UISearchDisplayDelegate> and in the navigationController:willShowViewController:animated: method set the delegate of the searchDisplayController to self viewController.searchDisplayController.delegate = self;