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];
}
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 this block of code in my xcode project. I am having trouble being able to click the button and to make this work. The button displays in my simulator but does not work when I click it. Does anyone have any ideas on what is going on here? It was working at one point but now seems to have failed. Maybe I accidentally changed a build setting? Or simulator setting? Any thoughts would be appreciated!!
Code for the button
-(void)viewDidLoad{
[super viewDidLoad];
UIBarButtonItem *actionButton = [[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemAction
target:self action:#selector(openWebLink)];
NSArray *items = [NSArray arrayWithObjects: actionButton, nil];
[self.toolbar setItems:items animated:NO];
[actionButton release]; }
Here is the code for the action:
-(void)openWebLink{
// open a dialog with an OK and cancel button
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:#"Do you want to apply for this job?"
delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:#"OK" otherButtonTitles:nil];
actionSheet.actionSheetStyle = UIActionSheetStyleDefault;
[actionSheet showFromToolbar:_toolbar];
[actionSheet release]; }
I've created UIAlertView with multiple buttons with the following code:
UIAlertView *alert = [[UIAlertView alloc] initWithFrame:CGRectMake(0, 0, 300, 200)];
alert.tag = TAG_ALERT0;
alert.title = #"Notes";
alert.delegate = self;
[alert addButtonWithTitle:#"Add Note"];
[alert addButtonWithTitle:#"Show Notes"];
[alert addButtonWithTitle:#"Cancel"];
[alert show];
I'm wondering if it is possible to add a different background color to each button?
Yes, you can but should not modify the look of UIAlertView since Apple hates that shit.
Instead, create your own UIView that mimics the alertView.
Also... does the initWithFrame method even make a difference?
Example... Try:
UIAlertView *alert = [[UIAlertView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
It won't make a difference.
So... I'd suggest:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Notes"
message:nil
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Add Note",#"Show Notes",nil];
[alert setTag:TAG_ALERT0];
[alert show];
But since you asked for sample code, the following example will be simple and to the point:
STATUTORY WARNING:
Apple doesn't like this
Doesn't work in iOS7
Example:
-(void)willPresentAlertView:(UIAlertView *)alertView
{
UILabel *theTitle = [alertView valueForKey:#"_titleLabel"];
[theTitle setTextColor:[UIColor orangeColor]];
NSMutableArray *arrButtons = [alertView valueForKey:#"_buttons"];
for (UIView *vwCurrent in arrButtons) {
[vwCurrent setBackgroundColor:[UIColor redColor]];
}
}
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;
}
}
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.