Keyboard appearing briefly when popping viewcontroller iOS - ios

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).

Related

how to stop view disappearing when navigation controller left bar button pressed

I am rookie to iOS .In my child view controller i made some modification in data. I inserted a done button to store a data and pop the view controller from navigation controller stack. if i press navigation controller back button it automatically goes to back without saving data. if i made any modification in data and then i pressed back button i need show alert as "modifications are made are sure want to go back". if the user press the cancel button in alert view i need to stop view disappearing and still stand on same view controller.If anybody have the answer please help me.
I think this is a way to do it
- (void)viewDidLoad{
[super viewDidLoad];
[self.navigationItem setLeftBarButtonItem:nil];
[self.navigationItem setHidesBackButton:YES];
UIButton *myButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 100, 44)];
[myButton setImage:[UIImage imageNamed:#"back.png"] forState:UIControlStateNormal];
//back.png = your image name
[myButton setTitle:#"Back" forState:UIControlStateNormal];
[myButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[myButton addTarget:self action:#selector(backButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *customBackButton = [[UIBarButtonItem alloc] initWithCustomView:myButton];
[self.navigationItem setLeftBarButtonItem:customBackButton];
}
- (void)backButtonTapped:(id)sender{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Message" message:#"modifications are made are sure want to go back" delegate:self cancelButtonTitle:#"Go Back" otherButtonTitles:#"Stay Here", nil];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView
clickedButtonAtIndex:(NSInteger)buttonIndex{
if (buttonIndex == [alertView cancelButtonIndex]){
[self.navigationController popViewControllerAnimated:YES];
}else{
//Stay on the page and do something
}
}
Don't forget to add <UIAlertViewDelegate>

Prevent leftBarButtonItem navigationItem show alert

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];
}

How to create a confirmation Pop Up when pushing Back button in iOS?

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;
}
}

Add method to UINavigationBar back button?

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.

Closing UIActionSheet

I have a UIActionSheet and I have added the following - UIPickerView and 2 BarButtonItems. I am trying to close the action sheet when someone clicks the Cancel Button (it is one of the bar button items).
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:nil cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles: nil];
[actionSheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];
CGRect pickerFrame = CGRectMake(0,40,0,0);
UIPickerView *pickerView = [[UIPickerView alloc] initWithFrame:pickerFrame];
pickerView.showsSelectionIndicator = YES;
pickerView.dataSource = self;
pickerView.delegate = self;
[actionSheet addSubview:pickerView];
UIToolbar *tools = [[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 40)];
tools.barStyle = UIBarStyleBlackOpaque;
[actionSheet addSubview:tools];
UIBarButtonItem *doneButton=[[UIBarButtonItem alloc]initWithTitle:#"Done" style:UIBarButtonItemStyleBordered target:self action:#selector(btnActinDoneClicked)];
doneButton.imageInsets=UIEdgeInsetsMake(200, 6, 50, 25);
UIBarButtonItem *CancelButton=[[UIBarButtonItem alloc]initWithTitle:#"Cancel" style:UIBarButtonItemStyleBordered target:self action:#selector(btnActinCancelClicked)]; //this is where the problem is
NSArray *array = [[NSArray alloc]initWithObjects:CancelButton, doneButton, nil];
[tools setItems:array];
[actionSheet showFromTabBar:self.tabBarController.tabBar];
[actionSheet setBounds:CGRectMake(0, 0, 320, 485)];
I have added another method to dismiss the action sheet -
-(IBAction)btnActinCancelClicked:(id)sender{
[sender dismissWithClickedButtonIndex:0 animated:YES];
}
The problem is that the app crashes when the BarButton is clicked. I think the problem is caused where the CancelButton is declared and it is unable to send a message to the btnActinCancelClicked method, but I can't figure out how to fix it.
Thanks
Your method is this;
-(IBAction)btnActinCancelClicked:(id)sender
So you need to add it like this (because it receives a parameter);
#selector(btnActinCancelClicked:)
So for example, if a method had three parameters you'd call it #selector(myMethod:andX:andY:)
Also, to access your UIActionSheet (not entirely sure this will work);
UIActionSheet *acSheet = sender.superView;
//Check if it is the ActionSheet here then dismiss it
[acSheet dismissWithClickedButtonIndex:0 animated:YES];
It's not the sender you want to dismiss. It's the ActionSheet. You'll need a reference for that and change your code for something like:
- (IBAction)btnActinCancelClicked:(id)sender{
[self.actionSheet dismissWithClickedButtonIndex:0 animated:YES];
}

Resources